Mi idea es introducir en una consola números binarios que lo detecta y los traduce a código ensamblador.
Hoja de datos PIC16F84A:
Ver enlace.
Página 22. Organización de la memoria de datos:
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:
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:
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.
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:
;----- 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:
;==========================================================================
;
; 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
Pseudocódigo de nuestro compañero del foro explorer:
Código:
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.