Binario en el asm de los PIC

Foro dedicado a la emulación de sistemas clásicos en el PC o en otros sistemas.
REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 27 Jul 2017, 19:13

¿Cómo cuál?

Avatar de Usuario
explorer
MSX Turbo R
MSX Turbo R
Mensajes: 398
Registrado: 11 May 2014, 17:10
Sistema Favorito: Atari ST
primer_sistema: Atari 800XL/600XL
consola_favorita: Atari 2600
Primera consola: Atari 2600
Ubicación: Valladolid, España
Gracias dadas: 2 veces
Gracias recibidas: 138 veces
Contactar:

Re: Binario en el asm de los PIC

Mensajepor explorer » 27 Jul 2017, 21:58

Me refería que el significado de los bits más bajos cambia según sean los bits más altos.

La CALL destino, por ejemplo, que sería

100 kkk kkkk kkkk

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 28 Jul 2017, 01:20

Ahora que me fijo bien, no solo está las x qu epueden ser 1 ó 0, da igual su valor.

Tanto como las f como las d. Hablando de las k, también están las b.

Pues todo eso hay que tenerlo en cuenta.



00001000 1 000 0110

MOVF H'0006', H'0001'

MOVF PORTB, F

switch(byte)
{
case 0x0886
printf("nemonico fulano");
break;
....
}

Ni más case hay que hacer.

08 son las intrucciones como sabrás y el conjunto del W y F más el PORTB es el 66

case 0x0886.

Fácil por ahora.

Avatar de Usuario
explorer
MSX Turbo R
MSX Turbo R
Mensajes: 398
Registrado: 11 May 2014, 17:10
Sistema Favorito: Atari ST
primer_sistema: Atari 800XL/600XL
consola_favorita: Atari 2600
Primera consola: Atari 2600
Ubicación: Valladolid, España
Gracias dadas: 2 veces
Gracias recibidas: 138 veces
Contactar:

Re: Binario en el asm de los PIC

Mensajepor explorer » 28 Jul 2017, 11:01

Como las instrucciones tienen 14 bits, yo primero dividiría el problema en sacar los dos bits más altos y luego los cuatro siguientes.

Viendo la tabla 7-2 verás que los dos primeros agrupan las instrucciones en tres grupos. Y los cuatro bits siguientes (a veces, solo dos) definen la instrucción en concreto, dejando el resto de bits para indicar destino y operando.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 28 Jul 2017, 20:12

¿Puedes hacer un ejemplo de lo que te refieras para estar seguro?

Avatar de Usuario
explorer
MSX Turbo R
MSX Turbo R
Mensajes: 398
Registrado: 11 May 2014, 17:10
Sistema Favorito: Atari ST
primer_sistema: Atari 800XL/600XL
consola_favorita: Atari 2600
Primera consola: Atari 2600
Ubicación: Valladolid, España
Gracias dadas: 2 veces
Gracias recibidas: 138 veces
Contactar:

Re: Binario en el asm de los PIC

Mensajepor explorer » 29 Jul 2017, 02:37

No sé el lenguaje que vas a usar, pero en una especie de pseudo lenguaje, sería algo así:

Código: Seleccionar todo

bits1413 = (0b11_0000_0000_0000 & opcode) >> 12;      // extraemos los dos bits superiores

switch (bits1413) {
   case 0b00:
      // en este caso, el tercer nibble es la operación, el bit 7 es la suboperación o destino, y el resto, el operando
      nibble3  = (0b00_1111_0000_0000 & opcode) >> 8;
      bit7     = (0b00_0000_1000_0000 & opcode) >> 7;
      operando = (0b00_0000_0111_1111 & opcode);

      switch (bit7) {
         case 0:
            reg = 'W';
            break;
         case 1;
            reg = 'F';
            break;
      }

      switch (nibble3) {
         
         case 0x0:
            switch (bit7) {
               case 1:
                  printf("MOVWF %x\n", operando);
                  break;
               case 0;
                  // aquí pueden ocurrir varios casos, según el primer nibble
                  nibble1 = (0b00_0000_0000_1111 & opcode);
                  switch (nibble1) {
                     case 0x0:
                        printf("NOP\n");
                        break;
                     case 0x4:
                        printf("CLRWDT\n");
                        break;
                     case 0x9:
                        printf("RETFIE\n");
                        break;
                     case 0x8:
                        printf("RETURN\n");
                        break;
                     case 0x3:
                        printf("SLEEP\n");
                        break;
                  }
                  break;
            }
            break;
         case 0x1:
            switch (bit7) {
               case 0:
                  printf("CLRW\n");
                  break;
               case 1;
                  printf("CLRF %x\n", operando);
                  break;
            }
            break;
         case 0x2:
            printf("SUBWF %x,%c\n", operando, reg);
            break;
         case 0x3:
            printf("DECF %x,%c\n", operando, reg);
            break;
         case 0x4:
            printf("IORWF %x,%c\n", operando, reg);
            break;
         case 0x5:
            printf("ANDWF %x,%c\n", operando, reg);
            break;
         case 0x6:
            printf("XORWF %x,%c\n", operando, reg);
            break;
         case 0x7:
            printf("ADDWF %x,%c\n", operando, reg);
            break;
         case 0x8:
            printf("MOVF %x,%c\n", operando, reg);
            break;
         case 0x9:
            printf("COMF %x,%c\n", operando, reg);
            break;
         case 0xA:
            printf("INCF %x,%c\n", operando, reg);
            break;
         case 0xB:
            printf("DECFSZ %x,%c\n", operando, reg);
            break;
         case 0xC:
            printf("RRF %x,%c\n", operando, reg);
            break;
         case 0xD:
            printf("RLF %x,%c\n", operando, reg);
            break;
         case 0xE:
            printf("SWAPF %x,%c\n", operando, reg);
            break;
         case 0xF:
            printf("INCFSZ %x,%c\n", operando, reg);
            break;
      }
      break;
   case 0b01:
      // en este caso, los bits 12 y 11 es la suboperación, los bits 8, 9 y 10 es el número de bit, y el resto, el operando
      subop    = (0b00_1100_0000_0000 & opcode) >> 10;
      bit      = (0b00_0011_1000_0000 & opcode) >> 7;
      operando = (0b00_0000_0111_1111 & opcode);

      switch (subop) {
         case 0x0;
            printf("BCF %x,%d\n", operando, bit);
            break;
         case 0x1;
            printf("BSF %x,%d\n", operando, bit);
            break;
         case 0x2;
            printf("BTFSC %x,%d\n", operando, bit);
            break;
         case 0x3;
            printf("BTFSS %x,%d\n", operando, bit);
            break;
      }
      break;
   case 0b10:
      // ver el bit 12. El resto es el operando
      bit12    = (0b00_1000_0000_0000 & opcode) >> 11;
      operando = (0b00_0111_1111_1111 & opcode);

      switch (bit12) {
         case 0:
            printf("CALL %x\n", operando);
            break;
         case 1:
            printf("GOTO %x\n", operando);
            break;
      }
      break;
   case 0b11:
      // el tercer nibble es la suboperación, y el resto, el operando
      nibble3  = (0b00_1111_0000_0000 & opcode) >> 8;
      operando = (0b00_0000_1111_1111 & opcode);
      
      switch (nibble3) {
         case 0b0000:
         case 0b0001:
         case 0b0010:
         case 0b0011:
            printf("MOVLW %x\n", operando);
            break;
         case 0b0100:
         case 0b0101:
         case 0b0110:
         case 0b0111:
            printf("RETLW %x\n", operando);
            break;
         case 0b1000:
            printf("IORLW %x\n", operando);
            break;
         case 0b1001:
            printf("ANDLW %x\n", operando);
            break;
         case 0b1010:
            printf("XORLW %x\n", operando);
            break;
         case 0b1100:
         case 0b1101:
            printf("SUBLW %x\n", operando);
            break;
         case 0b1110:
         case 0b1111:
            printf("ADDLW %x\n", operando);
            break;
      }
      break;
}

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 29 Jul 2017, 10:05

Buenas:

Menudo curro te haz pegado con el programa. Felicidades. ;)

Suelo trabajar en C#.
Si tengo este programa del PIC16F84A ya compilado. Su hex queda así:

Código: Seleccionar todo

:020000040000FA
:10000000831686011F308500831206100518062806
:10001000051806280E28051C0B2806280C1C11287C
:100020001528061001308C00062806148C010628BD
:1000300000000000000000000000000008000000B8
:10004000A4302B28000040302B281F302B28000024
:100050000E302B2805308D008D0B2C280800C83061
:100060003E2864303E2832303E2814303E280A3084
:100070003E2805303E2802303E2801308E00F930FF
:100080008D0000008D0B41288E0B3F280800C830E2
:1000900052286430522832305228143052280A3004
:1000A000522805308F0064308E00F9308D0000003A
:0E00B0008D0B57288E0B55288F0B53280800F8
:02400E00F13F80
:00000001FF


Saber más sobre del hex.
https://es.wikipedia.org/wiki/Intel_HEX

En la librerta o en un folio escribo estas intrucciones. Lo qu ehace es encender y apagar un Led con el mismo pulsador y tiene antirrebotes.

Código en asm:

Código: Seleccionar todo

; ZONA DE DATOS **********************************************************************

   LIST      P=16F84A
   INCLUDE      <P16F84A.INC>
   __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK 0x0C
    Flag
    ENDC

; ZONA DE CÓDIGOS ********************************************************************

   ORG    0                  ; El programa comienza en la dirección 0.
Inicio
   bsf      STATUS,RP0            ; Acceso al Banco 1.
   clrf   PORTB               ; Las líneas del Puerto B se configuran como salida.
   movlw   b'00011111'            ; Las 5 líneas del Puerto A se configuran como entrada.
   movwf   PORTA
   bcf      STATUS,RP0            ; Acceso al Banco 0.
   bcf      PORTB,0

Principal
   btfsc   PORTA,0               ; ¿Pulsador presionado?, ¿(Pulsador)=0?
   goto   Principal            ; No. Vuelve a leerlo.
;   call   Retardo_20ms         ; Espera que se estabilicen los niveles de tensión.
   btfsc   PORTA,0               ; Comprueba si es un rebote.
   goto   Principal            ; Era rebote y sale fuera.
   goto   Led

EsperaDejePulsar
   btfss   PORTA,0               ; ¿Dejó de pulsar?, ¿(Pulsador)=1?
   goto   EsperaDejePulsar      ; No. Espere que deje de pulsar.
   goto   Principal   

Led
   btfss   Flag,0
   goto   Led_OFF
   goto   Led_ON

Led_OFF
   bcf      PORTB,0
   movlw   .1
   movwf   Flag
   goto   Principal

Led_ON
   bsf      PORTB,0
   clrf   Flag
   goto Principal
   
   INCLUDE <RETARDOS.INC>
   END   


Como puedes ver, hay que tener en cuenta esto del código:
INCLUDE <P16F84A.INC>

Que es la lista externa ya indicada aquí. Más el otro archivo externo llamado INCLUDE <RETARDOS.INC>, todo esto tiene que estar en un mismo archivo como se hacía antes.

Como voy hacer un simulador primero en la consola de C#, si funciona, diseño y monto físicamente programar el PIC16F84A a base de binario y físicamente. Se que es una tontería pero es un retillo y curiosidad, :D :D :D .

Algo ya han hecho con Arduino.
https://create.arduino.cc/projecthub/da ... tor-3594a6

Analizando tu pseudo, pensé que ibas atacar el nibble más bajo. viendo la tabla, hay 3 tipos. Traduje la tabla.

Imagen

Imagen

Saludos.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 12 Ago 2017, 12:22

@explorer

¿Entiendes el Java?

Mi idea es adaptar tu pseudocódigo a C#, primero por mis amigos lo haremos a Java, si todo funciona de maravilla, lo adaptamos también al C#, C++ CLR y VB .net en modo consola.

Para dejarlo más ordenado ya que hay gente leyendo este tema,lo pongo en resumen y depaso no me llegan tantas preguntas en privado cuando lo pueden hacer por aquí.

Hoja de datos PIC16F84A:

Ver enlace.

Página 22. Organización de la memoria de datos:
bbbbbbbbbbbbbbb.png
bbbbbbbbbbbbbbb.png (27.69 KiB) Visto 8372 veces


El archivo p16f84a.inc que encuentras en el directorio en mi caso cuando instalé MPLAB X v4.00.
C:\Program Files (x86)\Microchip\MPLABX\v4.00\mpasmx

p16f84aa.inc:

Código: Seleccionar todo

        LIST

;==========================================================================
; Build date : May 17 2017
;  MPASM PIC16F84A processor include
;
;  (c) Copyright 1999-2017 Microchip Technology, All rights reserved
;==========================================================================

        NOLIST

;==========================================================================
;  This header file defines configurations, registers, and other useful
;  bits of information for the PIC16F84A microcontroller.  These names
;  are taken to match the data sheets as closely as possible.
;
;  Note that the processor must be selected before this file is included.
;  The processor may be selected the following ways:
;
;       1. Command line switch:
;               C:\MPASM MYFILE.ASM /PIC16F84A
;       2. LIST directive in the source file
;               LIST   P=PIC16F84A
;       3. Processor Type entry in the MPASM full-screen interface
;       4. Setting the processor in the MPLAB Project Dialog
;==========================================================================

;==========================================================================
;
;       Verify Processor
;
;==========================================================================
        IFNDEF __16F84A
           MESSG "Processor-header file mismatch.  Verify selected processor."
        ENDIF



;==========================================================================
;
;       Register Definitions
;
;==========================================================================

W                EQU  H'0000'
F                EQU  H'0001'

;----- Register Files -----------------------------------------------------

;-----Bank0------------------
INDF             EQU  H'0000'
TMR0             EQU  H'0001'
PCL              EQU  H'0002'
STATUS           EQU  H'0003'
FSR              EQU  H'0004'
PORTA            EQU  H'0005'
PORTB            EQU  H'0006'
EEDATA           EQU  H'0008'
EEADR            EQU  H'0009'
PCLATH           EQU  H'000A'
INTCON           EQU  H'000B'

;-----Bank1------------------
OPTION_REG       EQU  H'0081'
TRISA            EQU  H'0085'
TRISB            EQU  H'0086'
EECON1           EQU  H'0088'
EECON2           EQU  H'0089'

;----- STATUS Bits -----------------------------------------------------
C                EQU  H'0000'
DC               EQU  H'0001'
Z                EQU  H'0002'
NOT_PD           EQU  H'0003'
NOT_TO           EQU  H'0004'
IRP              EQU  H'0007'

RP0              EQU  H'0005'
RP1              EQU  H'0006'


;----- PORTA Bits -----------------------------------------------------
RA0              EQU  H'0000'
RA1              EQU  H'0001'
RA2              EQU  H'0002'
RA3              EQU  H'0003'
RA4              EQU  H'0004'


;----- PORTB Bits -----------------------------------------------------
RB0              EQU  H'0000'
RB1              EQU  H'0001'
RB2              EQU  H'0002'
RB3              EQU  H'0003'
RB4              EQU  H'0004'
RB5              EQU  H'0005'
RB6              EQU  H'0006'
RB7              EQU  H'0007'


;----- INTCON Bits -----------------------------------------------------
RBIF             EQU  H'0000'
INTF             EQU  H'0001'
T0IF             EQU  H'0002'
RBIE             EQU  H'0003'
INTE             EQU  H'0004'
T0IE             EQU  H'0005'
EEIE             EQU  H'0006'
GIE              EQU  H'0007'

TMR0IF           EQU  H'0002'
TMR0IE           EQU  H'0005'


;----- OPTION_REG Bits -----------------------------------------------------
PSA              EQU  H'0003'
T0SE             EQU  H'0004'
T0CS             EQU  H'0005'
INTEDG           EQU  H'0006'
NOT_RBPU         EQU  H'0007'

PS0              EQU  H'0000'
PS1              EQU  H'0001'
PS2              EQU  H'0002'


;----- TRISA Bits -----------------------------------------------------
TRISA0           EQU  H'0000'
TRISA1           EQU  H'0001'
TRISA2           EQU  H'0002'
TRISA3           EQU  H'0003'
TRISA4           EQU  H'0004'


;----- TRISB Bits -----------------------------------------------------
TRISB0           EQU  H'0000'
TRISB1           EQU  H'0001'
TRISB2           EQU  H'0002'
TRISB3           EQU  H'0003'
TRISB4           EQU  H'0004'
TRISB5           EQU  H'0005'
TRISB6           EQU  H'0006'
TRISB7           EQU  H'0007'


;----- EECON1 Bits -----------------------------------------------------
RD               EQU  H'0000'
WR               EQU  H'0001'
WREN             EQU  H'0002'
WRERR            EQU  H'0003'
EEIF             EQU  H'0004'




;==========================================================================
;
;       RAM Definitions
;
;==========================================================================
       __MAXRAM  H'00CF'
       __BADRAM  H'0007'
       __BADRAM  H'0050'-H'007F'
       __BADRAM  H'0087'

;==========================================================================
;
;       Configuration Bits
;
;   NAME            Address
;   CONFIG            2007h
;
;==========================================================================

; The following is an assignment of address values for all of the
; configuration registers for the purpose of table reads
_CONFIG         EQU  H'2007'

;----- CONFIG Options --------------------------------------------------
_FOSC_LP             EQU  H'3FFC'; LP oscillator
_LP_OSC              EQU  H'3FFC'; LP oscillator
_FOSC_XT             EQU  H'3FFD'; XT oscillator
_XT_OSC              EQU  H'3FFD'; XT oscillator
_FOSC_HS             EQU  H'3FFE'; HS oscillator
_HS_OSC              EQU  H'3FFE'; HS oscillator
_FOSC_EXTRC          EQU  H'3FFF'; RC oscillator
_RC_OSC              EQU  H'3FFF'; RC oscillator

_WDTE_OFF            EQU  H'3FFB'; WDT disabled
_WDT_OFF             EQU  H'3FFB'; WDT disabled
_WDTE_ON             EQU  H'3FFF'; WDT enabled
_WDT_ON              EQU  H'3FFF'; WDT enabled

_PWRTE_ON            EQU  H'3FF7'; Power-up Timer is enabled
_PWRTE_OFF           EQU  H'3FFF'; Power-up Timer is disabled

_CP_ON               EQU  H'000F'; All program memory is code protected
_CP_OFF              EQU  H'3FFF'; Code protection disabled

;----- DEVID Equates --------------------------------------------------
_DEVID1          EQU  H'2006'

;----- IDLOC Equates --------------------------------------------------
_IDLOC0          EQU  H'2000'
_IDLOC1          EQU  H'2001'
_IDLOC2          EQU  H'2002'
_IDLOC3          EQU  H'2003'

        LIST


Página 35. SISTEMA DE INSTRUCCIONES:
Imagen

Para dejarlo mejor explicado, cogemos por ejemplo el registro MOVF que puedes ver en l apágin a36 de la hoja de datos del PIC16F84A.

bbbbbbbbbbbbbbb2.png
bbbbbbbbbbbbbbb2.png (147.59 KiB) Visto 8372 veces


Como podrás ver en la tabla, MOVF corresponde al 00 1000, o lo que es lo mismo, añadir dos ceros más al principio, 00001000.

El registro PORTB que muestra en el archivo p16f84a.inc:

Código: Seleccionar todo

;----- Register Files -----------------------------------------------------

;-----Bank0------------------
PORTB            EQU  H'0006'


Del hexadecimal H'0006' al binario es: 000 0110

Mirando el archivo p16f84a.inc de arriba:

Código: Seleccionar todo

;==========================================================================
;
;       Register Definitions
;
;==========================================================================

W                EQU  H'0000'
F                EQU  H'0001'


Elegimos la F que corresponde guardar en el propio registro, es un 1. La d es el lugar de destino, W que equivale a 0 se guarda en el registro de trabajo. La F que equivale a 1 se guarda en el registro.

En resumen:
MOVF PORTB, F

MOVF H'0006', H'0001'

00001000 1 000 0110

Imagen

Pseudocódigo de nuestro compañero del foro explorer:

Código: Seleccionar todo

bits1413 = (0b11_0000_0000_0000 & opcode) >> 12;      // extraemos los dos bits superiores

switch (bits1413) {
   case 0b00:
      // en este caso, el tercer nibble es la operación, el bit 7 es la suboperación o destino, y el resto, el operando
      nibble3  = (0b00_1111_0000_0000 & opcode) >> 8;
      bit7     = (0b00_0000_1000_0000 & opcode) >> 7;
      operando = (0b00_0000_0111_1111 & opcode);

      switch (bit7) {
         case 0:
            reg = 'W';
            break;
         case 1;
            reg = 'F';
            break;
      }

      switch (nibble3) {
         
         case 0x0:
            switch (bit7) {
               case 1:
                  printf("MOVWF %x\n", operando);
                  break;
               case 0;
                  // aquí pueden ocurrir varios casos, según el primer nibble
                  nibble1 = (0b00_0000_0000_1111 & opcode);
                  switch (nibble1) {
                     case 0x0:
                        printf("NOP\n");
                        break;
                     case 0x4:
                        printf("CLRWDT\n");
                        break;
                     case 0x9:
                        printf("RETFIE\n");
                        break;
                     case 0x8:
                        printf("RETURN\n");
                        break;
                     case 0x3:
                        printf("SLEEP\n");
                        break;
                  }
                  break;
            }
            break;
         case 0x1:
            switch (bit7) {
               case 0:
                  printf("CLRW\n");
                  break;
               case 1;
                  printf("CLRF %x\n", operando);
                  break;
            }
            break;
         case 0x2:
            printf("SUBWF %x,%c\n", operando, reg);
            break;
         case 0x3:
            printf("DECF %x,%c\n", operando, reg);
            break;
         case 0x4:
            printf("IORWF %x,%c\n", operando, reg);
            break;
         case 0x5:
            printf("ANDWF %x,%c\n", operando, reg);
            break;
         case 0x6:
            printf("XORWF %x,%c\n", operando, reg);
            break;
         case 0x7:
            printf("ADDWF %x,%c\n", operando, reg);
            break;
         case 0x8:
            printf("MOVF %x,%c\n", operando, reg);
            break;
         case 0x9:
            printf("COMF %x,%c\n", operando, reg);
            break;
         case 0xA:
            printf("INCF %x,%c\n", operando, reg);
            break;
         case 0xB:
            printf("DECFSZ %x,%c\n", operando, reg);
            break;
         case 0xC:
            printf("RRF %x,%c\n", operando, reg);
            break;
         case 0xD:
            printf("RLF %x,%c\n", operando, reg);
            break;
         case 0xE:
            printf("SWAPF %x,%c\n", operando, reg);
            break;
         case 0xF:
            printf("INCFSZ %x,%c\n", operando, reg);
            break;
      }
      break;
   case 0b01:
      // en este caso, los bits 12 y 11 es la suboperación, los bits 8, 9 y 10 es el número de bit, y el resto, el operando
      subop    = (0b00_1100_0000_0000 & opcode) >> 10;
      bit      = (0b00_0011_1000_0000 & opcode) >> 7;
      operando = (0b00_0000_0111_1111 & opcode);

      switch (subop) {
         case 0x0;
            printf("BCF %x,%d\n", operando, bit);
            break;
         case 0x1;
            printf("BSF %x,%d\n", operando, bit);
            break;
         case 0x2;
            printf("BTFSC %x,%d\n", operando, bit);
            break;
         case 0x3;
            printf("BTFSS %x,%d\n", operando, bit);
            break;
      }
      break;
   case 0b10:
      // ver el bit 12. El resto es el operando
      bit12    = (0b00_1000_0000_0000 & opcode) >> 11;
      operando = (0b00_0111_1111_1111 & opcode);

      switch (bit12) {
         case 0:
            printf("CALL %x\n", operando);
            break;
         case 1:
            printf("GOTO %x\n", operando);
            break;
      }
      break;
   case 0b11:
      // el tercer nibble es la suboperación, y el resto, el operando
      nibble3  = (0b00_1111_0000_0000 & opcode) >> 8;
      operando = (0b00_0000_1111_1111 & opcode);
     
      switch (nibble3) {
         case 0b0000:
         case 0b0001:
         case 0b0010:
         case 0b0011:
            printf("MOVLW %x\n", operando);
            break;
         case 0b0100:
         case 0b0101:
         case 0b0110:
         case 0b0111:
            printf("RETLW %x\n", operando);
            break;
         case 0b1000:
            printf("IORLW %x\n", operando);
            break;
         case 0b1001:
            printf("ANDLW %x\n", operando);
            break;
         case 0b1010:
            printf("XORLW %x\n", operando);
            break;
         case 0b1100:
         case 0b1101:
            printf("SUBLW %x\n", operando);
            break;
         case 0b1110:
         case 0b1111:
            printf("ADDLW %x\n", operando);
            break;
      }
      break;
}


Yo y un amigo lo valos a traducir por el momento a Java que es el que entiende mejor, luego haré en otros lenguajes para quien le guste, como dije arriba, C#, C++ CLR y VB .net.

Si no tienen algo claro, avisen.

Un cordial saludo.

REHome
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 145
Registrado: 19 Abr 2013, 22:01
Sistema Favorito: Spectrum +2
primer_sistema: Spectrum +2
Gracias dadas: 3 veces
Gracias recibidas: 2 veces

Re: Binario en el asm de los PIC

Mensajepor REHome » 15 Ago 2017, 00:53

Hola:

Ya se ha hecho algo a secar por un amigo pero no está del todo completo, solo muestra del binario establecido como ejemplo y lo muestra en código ensamblador.

Puedes usar el NetBeanso el Eclipse.

bbbbbbbbbbbbbbb3.png
bbbbbbbbbbbbbbb3.png (54.3 KiB) Visto 8331 veces


bbbbbbbbbbbbbbb4.png
bbbbbbbbbbbbbbb4.png (105.23 KiB) Visto 8331 veces


Descompila.java

Código: Seleccionar todo

package descompila;
import java.io.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Descompila {
   

   public static void main(String [] arg) {
       
       descompilar(new TroceadoEnBits(0x0886));
   }
   static void print(String cadena){
      System.out.println(cadena);
   }
   static String direccion(int operando){
      String registro="";
      switch(operando){
         case 0x6:
            registro="PORTB";
            break;
            //chago aqui vete completando la tabla de REGISTER FILE MAP
         default:
            registro= Integer.toHexString(operando);
            break;
      }
      return registro;
   }
   static void descompilar(TroceadoEnBits opcode){

      int bits1312 =opcode.dameRango(12, 13);// (0x3000 & opcode) >> 12;      // extraemos los dos bits superiores
        String operando;
      switch (bits1312) {
         case 0:
            // en este caso, el tercer nibble es la operación, el bit 7 es la suboperación o destino, y el resto, el operando
            int nibble3  = opcode.dameRango(8, 11);//(0x0f00 & opcode) >> 8;
            int bit7     = opcode.dameRango(7, 7);//(0x0080 & opcode) >> 7;
            operando = direccion(opcode.dameRango(0, 6)); //direccion(0x007f & opcode);
              String reg="";
            switch (bit7) {
               case 0:
                  reg = ", W ";
                  break;
               case 1:
                  reg = ", F ";
                  break;
            }

            switch (nibble3) {
               
               case 0x0:
                  switch (bit7) {
                     case 1:
                        print("MOVWF " + operando);
                        break;
                     case 0:
                        // aquí pueden ocurrir varios casos, según el primer nibble
                        int nibble1 =opcode.dameRango(0, 3);// (0x000f & opcode);
                        switch (nibble1) {
                           case 0x0:
                              print("NOP");
                              break;
                           case 0x4:
                              print("CLRWDT");
                              break;
                           case 0x9:
                              print("RETFIE");
                              break;
                           case 0x8:
                              print("RETURN");
                              break;
                           case 0x3:
                              print("SLEEP");
                              break;
                        }
                        break;
                  }
                  break;
               case 0x1:
                  switch (bit7) {
                     case 0:
                        print("CLRW");
                        break;
                     case 1:
                        print("CLRF " + operando);
                        break;
                  }
                  break;
               case 0x2:
                  print("SUBWF "+ operando + reg);
                  break;
               case 0x3:
                  print("DECF "+ operando + reg);
                  break;
               case 0x4:
                  print("IORWF "+ operando + reg);
                  break;
               case 0x5:
                  print("ANDWF "+ operando + reg);
                  break;
               case 0x6:
                  print("XORWF "+ operando + reg);
                  break;
               case 0x7:
                  print("ADDWF "+ operando + reg);
                  break;
               case 0x8:
                  print("MOVF "+ operando + reg);
                  break;
               case 0x9:
                  print("COMF "+ operando + reg);
                  break;
               case 0xA:
                  print("INCF "+ operando + reg);
                  break;
               case 0xB:
                  print("DECFSZ "+ operando + reg);
                  break;
               case 0xC:
                  print("RRF "+ operando + reg);
                  break;
               case 0xD:
                  print("RLF "+ operando + reg);
                  break;
               case 0xE:
                  print("SWAPF "+ operando + reg);
                  break;
               case 0xF:
                  print("INCFSZ "+ operando + reg);
                  break;
            }
            break;
         case 1:
            // en este caso, los bits 12 y 11 es la suboperación, los bits 8, 9 y 10 es el número de bit, y el resto, el operandojj
            int subop    = opcode.dameRango(8, 10);//(0x0c00 & opcode) >> 10;
            int bit      = opcode.dameRango(7, 9);//(0x0380 & opcode) >> 7;
            operando = opcode.dameRangoHex(0, 6);//Integer.toHexString(0x007f & opcode);

            switch (subop) {
               case 0x0:
                  print("BCF "+ operando + bit);
                  break;
               case 0x1:
                  print("BSF "+ operando + bit);
                  break;
               case 0x2:
                  print("BTFSC "+ operando + bit);
                  break;
               case 0x3:
                  print("BTFSS "+ operando + bit);
                  break;
            }
            break;
         case 2:
            // ver el bit 12. El resto es el operando
            int bit11    = opcode.dameRango(11, 11);//(0x0800 & opcode) >> 11;
            operando = opcode.dameRangoHex(0, 10);//Integer.toHexString(0x07ff & opcode);

            switch (bit11) {
               case 0:
                  print("CALL "+ operando);
                  break;
               case 1:
                  print("GOTO "+ operando);
                  break;
            }
            break;
         case 3:
            // el tercer nibble es la suboperación, y el resto, el operando
            nibble3  = opcode.dameRango(8, 11);//(0x0f00 & opcode) >> 8;
            operando = direccion(opcode.dameRango(0, 7));//direccion(0x00ff & opcode);
           
            switch (nibble3) {
               case 0:
               case 1:
               case 2:
               case 3:
                  print("MOVLW "+ operando);
                  break;
               case 4:
               case 5:
               case 6:
               case 7:
                  print("RETLW "+ operando);
                  break;
               case 8:
                  print("IORLW "+ operando);
                  break;
               case 9:
                  print("ANDLW "+ operando);
                  break;
               case 0xa:
                  print("XORLW "+ operando);
                  break;
                 
               case 0xb:
               case 0xc:
                  //cc no sé que pasa con 0xd
                  print("SUBLW "+ operando);
                  break;
               case 0xe:
               case 0xf:
                  print("ADDLW "+ operando);
                  break;
            }
            break;
      }      
   }
}



TroceadoEnBits.java

Código: Seleccionar todo

package descompila;

public class TroceadoEnBits {
   int bits;
   public TroceadoEnBits(int bits) {
      super();
      this.bits = bits;
   }   
   public int getBits() {
      return bits;
   }
   public void setBits(int bits) {
      this.bits = bits;
   }
   public int dameRango(int ini, int fin){
      int desde[]=new int[14],hasta[]=new int[14];
      desde[0]=0x3fff;  hasta[0]=0x1;
      desde[1]=0x3ffe;  hasta[1]=0x3;     
      desde[2]=0x3ffc;  hasta[2]=0x7;
      desde[3]=0x3ff8;  hasta[3]=0xf;
      desde[4]=0x3ff0;  hasta[4]=0x1f;
      desde[5]=0x3fe0;  hasta[5]=0x3f;
      desde[6]=0x3fc0;  hasta[6]=0x7f;
      desde[7]=0x3f80;  hasta[7]=0xff;
      desde[8]=0x3f00;  hasta[8]=0x1ff;
      desde[9]=0x3e00;  hasta[9]=0x3ff;
      desde[10]=0x3c00; hasta[10]=0x7ff;
      desde[11]=0x3800; hasta[11]=0xfff;
      desde[12]=0x3000; hasta[12]=0x1fff;
      desde[13]=0x2000; hasta[13]=0x3fff;
      return (desde[ini]&hasta[fin]&bits)>>ini;
   }
   public String dameRangoHex(int ini, int fin){
      return Integer.toHexString(dameRango(ini,fin));
   }
}


Lo que falta ahora es una entrada de datos en consola, por ejemplo, introducir estos datos.

00001000 1 000 0110

A la hora de instroducción de datos se pondrá todo junto, los 14 ó 16 bits.

000010001000 0110

Por cada entrada binaria que metan, al pulsar Enter muestra el código en ensamblador como puede ser este ejemplo:

MOVF PORTB, F

Saludos.

Avatar de Usuario
explorer
MSX Turbo R
MSX Turbo R
Mensajes: 398
Registrado: 11 May 2014, 17:10
Sistema Favorito: Atari ST
primer_sistema: Atari 800XL/600XL
consola_favorita: Atari 2600
Primera consola: Atari 2600
Ubicación: Valladolid, España
Gracias dadas: 2 veces
Gracias recibidas: 138 veces
Contactar:

Re: Binario en el asm de los PIC

Mensajepor explorer » 15 Ago 2017, 21:03

Pues no, no uso Java. Desde hace 20 años, precisamente. Es un lenguaje muy verboso (escribir muchas líneas para poder hacer algo).

Yo soy programador de Perl. Y el problema se puede resolver en una sola línea de comando :)

Código: Seleccionar todo

$ perl -E '$dat = pack "v*", 0b001000_1_000_0110; $l = length $dat; say sprintf ":%02x000000%s%s\n:00000001FF", $l, unpack("H*", $dat), unpack "H2", pack "C", 0x100 - ($l + unpack "%8C*", $dat) ' > kkk.hex; gpdasm -p p16f874a kkk.hex
000000:  0886  movf     0x6, f

Bueno, naturalmente, hay trampa: uso el desensamblador gpdasm de las gputils. El código Perl crea un archivo kkk.hex a partir de los dos bytes que queremos desensamblar, y se lo pasa al desensamblador, que genera el código para el micro indicado (p16f874a).

Desensambladores hay unos cuantos. Y algunos en código C. Seguro que en Java ya hay alguna cosa hecha. Cuestión de buscar.


Volver a “Emuladores”

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 6 invitados