/**************************************************************************\ * Microchip PIC16C62X Emulator * * * * Based On * * Microchip PIC16C5X Emulator * * Copyright Tony La Porta * * Originally written for the MAME project. * * * * * * Addressing architecture is based on the Harvard addressing scheme. * * * * Many thanks to those involved in the i8039 Disassembler * * as this was based on it. * * * * * * * * A Address to jump to. * * B Bit address within an 8-bit file register. * * D Destination select (0 = store result in W (accumulator)) * * (1 = store result in file register) * * F Register file address (00-1F). * * K Literal field, constant data. * * X Not used * * * \**************************************************************************/ #include "emu.h" #include static const UINT8 *rombase; static const UINT8 *rambase; static offs_t pcbase; #define READOP16(A) (rombase[(A) - pcbase] | (rombase[(A) + 1 - pcbase] << 8)) #define READARG16(A) (rambase[(A) - pcbase] | (rambase[(A) + 1 - pcbase] << 8)) typedef unsigned char byte; typedef unsigned short int word; #define FMT(a,b) a, b #define PTRS_PER_FORMAT 2 /* Registers bank 0/1 */ static const char *const regfile[32] = { "Reg$00 (INDF)", "Reg$01 (TMR0/OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (PORTA/TRISA)", "Reg$06 (PORTB/TRISB)", "Reg$07", "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIR1/PIE1)", "Reg$0D", "Reg$0E (none/PCON)", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (CMCON/VRCON)" }; /* Registers bank 1 */ /*static const char *const regfile1[32] = { "Reg$00 (INDF)", "Reg$01 (OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (TRISA)", "Reg$06 (TRISB)", "Reg$07", "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIE1)", "Reg$0D", "Reg$0E (PCON)", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (VRCON)" }; static const char **regfile[2] = { regfile0, regfile1 };*/ static const char *const dest[2] = { "W", "Reg" }; static const char *const PIC16C62xFormats[] = { FMT("0000000xx00000", "nop"), FMT("00000000001000", "return"), FMT("00000000001001", "retfie"), FMT("00000001100011", "sleep"), FMT("00000001100100", "clrwdt"), FMT("0000001fffffff", "movwf %F"), FMT("00000100000011", "clrw"), FMT("0000011fffffff", "clrf %F"), FMT("000010dfffffff", "subwf %F,%D"), FMT("000011dfffffff", "decf %F,%D"), FMT("000100dfffffff", "iorwf %F,%D"), FMT("000101dfffffff", "andwf %F,%D"), FMT("000110dfffffff", "xorwf %F,%D"), FMT("000111dfffffff", "addwf %F,%D"), FMT("001000dfffffff", "movf %F,%D"), FMT("001001dfffffff", "comf %F,%D"), FMT("001010dfffffff", "incf %F,%D"), FMT("001011dfffffff", "decfsz %F,%D"), FMT("001100dfffffff", "rrf %F,%D"), FMT("001101dfffffff", "rlf %F,%D"), FMT("001110dfffffff", "swapf %F,%D"), FMT("001111dfffffff", "incfsz %F,%D"), FMT("0100bbbfffffff", "bcf %F,%B"), FMT("0101bbbfffffff", "bsf %F,%B"), FMT("0110bbbfffffff", "btfsc %F,%B"), FMT("0111bbbfffffff", "btfss %F,%B"), FMT("1101xxkkkkkkkk", "retlw %K"), FMT("100aaaaaaaaaaa", "call %A"), FMT("101aaaaaaaaaaa", "goto %A"), FMT("1100xxkkkkkkkk", "movlw %K"), FMT("111000kkkkkkkk", "iorlw %K"), FMT("111001kkkkkkkk", "andlw %K"), FMT("111010kkkkkkkk", "xorlw %K"), FMT("11110xkkkkkkkk", "sublw %K"), FMT("11111xkkkkkkkk", "addlw %K"), NULL }; #define MAX_OPS ((ARRAY_LENGTH(PIC16C62xFormats) - 1) / PTRS_PER_FORMAT) struct PIC16C62xOpcode { word mask; /* instruction mask */ word bits; /* constant bits */ word extcode; /* value that gets extension code */ const char *parse; /* how to parse bits */ const char *fmt; /* instruction format */ }; static PIC16C62xOpcode Op[MAX_OPS+1]; static int OpInizialized = 0; static void InitDasm16C5x(void) { const char *p; const char *const *ops; word mask, bits; int bit; int i; ops = PIC16C62xFormats; i = 0; while (*ops) { p = *ops; mask = 0; bits = 0; bit = 13; while (*p && bit >= 0) { switch (*p++) { case '1': mask |= 1<= 0) { /* osd_printf_debug("{%c/%d}",*cp,bit); */ switch(*cp) { case 'a': a <<=1; a |= ((code & (1<