From 6e4a6b1f4aecb0ec7cab2c3dea9553f30f848a4c Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Thu, 17 Apr 2014 08:55:31 -0500 Subject: [PATCH] Added disassembler for 63701. --- src/dis63701.cpp | 161 +++++++++++++++++++++++++++++++++++++++++++++++ src/dis63701.h | 16 +++++ 2 files changed, 177 insertions(+) create mode 100644 src/dis63701.cpp create mode 100644 src/dis63701.h diff --git a/src/dis63701.cpp b/src/dis63701.cpp new file mode 100644 index 0000000..09fec5b --- /dev/null +++ b/src/dis63701.cpp @@ -0,0 +1,161 @@ +// +// 63701 disassembler +// +// by James Hammons +// +// (c) 2004, 2014 Underground Software +// + +#include "dis63701.h" + +#include +#include + + +// Private globals variables + +// Mode +// 0=ill, 1=ZP, 2=abs, 3=rel, 4=imm+ZP,X, 5=inh, 6=imm+ZP, 7=ZP,X, 8=imm, 9=long imm + +static char opcodeMode[256] = { + 0, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $0x + 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, // $4x + 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, + 7, 4, 4, 7, 7, 4, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7, // $6x + 2, 6, 6, 2, 2, 6, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2, + 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 3, 9, 9, // $8x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // $Ax + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, // $Cx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // $Ex + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +static char mnemonics[256][6] = { + "??? ","NOP ","??? ","??? ","LSRD ","ASLD ","TAP ","TPA ", // $0x + "INX ","DEX ","CLV ","SEV ","CLC ","SEC ","CLI ","SEI ", + "SBA ","CBA ","UND1 ","UND2 ","??? ","??? ","TAB ","TBA ", // $1x + "XGDX ","DAA ","SLP ","ABA ","??? ","??? ","??? ","??? ", + "BRA ","BRN ","BHI ","BLS ","BCC ","BCS ","BNE ","BEQ ", // $2x + "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ", + "TSX ","INS ","PULA ","PULB ","DES ","TXS ","PSHA ","PSHB ", // $3x + "PULX ","RTS ","ABX ","RTI ","PSHX ","MUL ","WAI ","SWI ", + "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ", // $4x + "ASLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ", + "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ", // $5x + "ASLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ", + "NEG ","AIM ","OIM ","COM ","LSR ","EIM ","ROR ","ASR ", // $6x + "ASL ","ROL ","DEC ","TIM ","INC ","TST ","JMP ","CLR ", + "NEG ","AIM ","OIM ","COM ","LSR ","EIM ","ROR ","ASR ", // $7x + "ASL ","ROL ","DEC ","TIM ","INC ","TST ","JMP ","CLR ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STA ", // $8x + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","BSR ","LDS ","STS ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ", // $9x + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ", // $Ax + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", + "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ", // $Bx + "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STB ", // $Cx + "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ", // $Dx + "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ", // $Ex + "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX ", + "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ", // $Fx + "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX " +}; + + +// +// Display bytes in mem in hex +// +static void WriteBytesToString(uint8_t * mem, uint16_t src, uint32_t dst, char * s) +{ + const char hex[17] = "0123456789ABCDEF"; + + if (s == 0) + return; + + sprintf(s, "%04X: ", src); + + // That should fix the FFFF bug... + if (src > dst) + dst += 0x10000; + + for(uint32_t i=src; i> 4]; + s[6 + ((i - src) * 3) + 1] = hex[mem[i & 0xFFFF] & 0xF]; + } +} + + +// +// Decode a 63701 instruction +// +uint32_t Decode63701(uint8_t * mem, uint16_t pc, char * buffer) +{ + if (buffer == 0) + return 0; + + char instruction[80], byteString[80]; + + uint16_t addr = pc, offset; + uint8_t opcode = mem[addr++], extra; + + // Decode the addressing mode... + switch (opcodeMode[opcode]) + { + case 0: // Illegal + sprintf(instruction, "??? "); + break; + case 1: // Zero page + sprintf(instruction, "%s $%02X ", mnemonics[opcode], mem[addr++]); + break; + case 2: // Absolute + offset = (mem[addr + 0] << 8) | mem[addr + 1]; + addr += 2; + sprintf(instruction, "%s $%04X ", mnemonics[opcode], offset); + break; + case 3: // Relative + offset = addr + 1 + (int16_t)(int8_t)mem[addr]; + addr++; + sprintf(instruction, "%s $%04X ", mnemonics[opcode], offset); + break; + case 5: // Inherent + sprintf(instruction, "%s ", mnemonics[opcode]); + break; + case 7: // Indexed + sprintf(instruction, "%s $%02X,X ", mnemonics[opcode], mem[addr++]); + break; + case 8: // Immediate + sprintf(instruction, "%s #$%02X ", mnemonics[opcode], mem[addr++]); + break; + case 9: // Long Immediate + offset = (mem[addr + 0] << 8) | mem[addr + 1]; + addr += 2; + sprintf(instruction, "%s #$%04X ", mnemonics[opcode], offset); + break; + case 6: // Immediate + zero page + extra = mem[addr++]; + sprintf(instruction, "%s #$%02X, $%02X", mnemonics[opcode], extra, mem[addr++]); + break; + case 4: // Immediate + indexed + extra = mem[addr++]; + sprintf(instruction, "%s #$%02X, $%02X,X", mnemonics[opcode], extra, mem[addr++]); + break; + } + +//printf("D6[%s]\n", instruction); + WriteBytesToString(mem, pc, addr, byteString); + sprintf(buffer, "%s%s", byteString, instruction); + + return (addr < pc ? addr - pc + 0x10000 : addr - pc); +} + diff --git a/src/dis63701.h b/src/dis63701.h new file mode 100644 index 0000000..8fcad9c --- /dev/null +++ b/src/dis63701.h @@ -0,0 +1,16 @@ +// +// DIS63701.H +// +// by James Hammons +// (C) 2004, 2014 Underground Software +// + +#ifndef __DIS63701_H__ +#define __DIS63701_H__ + +#include + +uint32_t Decode63701(uint8_t * mem, uint16_t pc, char *); + +#endif // __DIS63701_H__ + -- 2.37.2