6 // (c) 2004, 2014 Underground Software
15 // Private globals variables
18 // 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
20 static char opcodeMode[256] = {
21 0, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $0x
22 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
23 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x
24 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
25 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, // $4x
26 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
27 7, 4, 4, 7, 7, 4, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7, // $6x
28 2, 6, 6, 2, 2, 6, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2,
29 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 3, 9, 9, // $8x
30 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
31 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // $Ax
32 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
33 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, // $Cx
34 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
35 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // $Ex
36 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
39 static char mnemonics[256][6] = {
40 "??? ","NOP ","??? ","??? ","LSRD ","ASLD ","TAP ","TPA ", // $0x
41 "INX ","DEX ","CLV ","SEV ","CLC ","SEC ","CLI ","SEI ",
42 "SBA ","CBA ","UND1 ","UND2 ","??? ","??? ","TAB ","TBA ", // $1x
43 "XGDX ","DAA ","SLP ","ABA ","??? ","??? ","??? ","??? ",
44 "BRA ","BRN ","BHI ","BLS ","BCC ","BCS ","BNE ","BEQ ", // $2x
45 "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ",
46 "TSX ","INS ","PULA ","PULB ","DES ","TXS ","PSHA ","PSHB ", // $3x
47 "PULX ","RTS ","ABX ","RTI ","PSHX ","MUL ","WAI ","SWI ",
48 "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ", // $4x
49 "ASLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ",
50 "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ", // $5x
51 "ASLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ",
52 "NEG ","AIM ","OIM ","COM ","LSR ","EIM ","ROR ","ASR ", // $6x
53 "ASL ","ROL ","DEC ","TIM ","INC ","TST ","JMP ","CLR ",
54 "NEG ","AIM ","OIM ","COM ","LSR ","EIM ","ROR ","ASR ", // $7x
55 "ASL ","ROL ","DEC ","TIM ","INC ","TST ","JMP ","CLR ",
56 "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STA ", // $8x
57 "EORA ","ADCA ","ORAA ","ADDA ","CPX ","BSR ","LDS ","STS ",
58 "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ", // $9x
59 "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ",
60 "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ", // $Ax
61 "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ",
62 "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ", // $Bx
63 "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ",
64 "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STB ", // $Cx
65 "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX ",
66 "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ", // $Dx
67 "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX ",
68 "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ", // $Ex
69 "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX ",
70 "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ", // $Fx
71 "EORB ","ADCB ","ORAB ","ADDB ","LDD ","STD ","LDX ","STX "
76 // Display bytes in mem in hex
78 static void WriteBytesToString(uint8_t * mem, uint16_t src, uint32_t dst, char * s)
80 const char hex[17] = "0123456789ABCDEF";
85 sprintf(s, "%04X: ", src);
87 // That should fix the FFFF bug...
91 for(uint32_t i=src; i<dst; i++)
93 s[6 + ((i - src) * 3) + 0] = hex[mem[i & 0xFFFF] >> 4];
94 s[6 + ((i - src) * 3) + 1] = hex[mem[i & 0xFFFF] & 0xF];
100 // Decode a 63701 instruction
102 uint32_t Decode63701(uint8_t * mem, uint16_t pc, char * buffer)
107 char instruction[80], byteString[80];
109 uint16_t addr = pc, offset;
110 uint8_t opcode = mem[addr++], extra;
112 // Decode the addressing mode...
113 switch (opcodeMode[opcode])
116 sprintf(instruction, "??? ");
119 sprintf(instruction, "%s $%02X ", mnemonics[opcode], mem[addr++]);
122 offset = (mem[addr + 0] << 8) | mem[addr + 1];
124 sprintf(instruction, "%s $%04X ", mnemonics[opcode], offset);
127 offset = addr + 1 + (int16_t)(int8_t)mem[addr];
129 sprintf(instruction, "%s $%04X ", mnemonics[opcode], offset);
132 sprintf(instruction, "%s ", mnemonics[opcode]);
135 sprintf(instruction, "%s $%02X,X ", mnemonics[opcode], mem[addr++]);
138 sprintf(instruction, "%s #$%02X ", mnemonics[opcode], mem[addr++]);
140 case 9: // Long Immediate
141 offset = (mem[addr + 0] << 8) | mem[addr + 1];
143 sprintf(instruction, "%s #$%04X ", mnemonics[opcode], offset);
145 case 6: // Immediate + zero page
147 sprintf(instruction, "%s #$%02X, $%02X", mnemonics[opcode], extra, mem[addr++]);
149 case 4: // Immediate + indexed
151 sprintf(instruction, "%s #$%02X, $%02X,X", mnemonics[opcode], extra, mem[addr++]);
155 //printf("D6[%s]\n", instruction);
156 WriteBytesToString(mem, pc, addr, byteString);
157 sprintf(buffer, "%s%s", byteString, instruction);
159 return (addr < pc ? addr - pc + 0x10000 : addr - pc);