--- /dev/null
+//
+// 63701 disassembler
+//
+// by James Hammons
+//
+// (c) 2004, 2014 Underground Software
+//
+
+#include "dis63701.h"
+
+#include <stdio.h>
+#include <string>
+
+
+// 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<dst; i++)
+ {
+ s[6 + ((i - src) * 3) + 0] = hex[mem[i & 0xFFFF] >> 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);
+}
+