5 // (c) 2005-2018 Underground Software
15 // Private global variables
17 static uint8_t op_mat[256] = {
18 14, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
19 13, 7, 5, 0, 2, 3, 3, 2, 14, 10, 14, 0, 8, 9, 9, 13,
20 8, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
21 13, 7, 5, 0, 3, 3, 3, 2, 14, 10, 14, 0, 9, 9, 9, 13,
22 14, 6, 0, 0, 0, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
23 13, 7, 5, 0, 0, 3, 3, 2, 14, 10, 14, 0, 0, 9, 9, 13,
24 14, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 11, 8, 8, 13,
25 13, 7, 5, 0, 3, 3, 3, 2, 14, 10, 14, 0, 12, 9, 9, 13,
26 13, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
27 13, 7, 5, 0, 3, 3, 4, 2, 14, 10, 14, 0, 8, 9, 9, 13,
28 1, 6, 1, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
29 13, 7, 5, 0, 3, 3, 4, 2, 14, 10, 14, 0, 9, 9, 10, 13,
30 1, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
31 13, 7, 5, 0, 0, 3, 3, 2, 14, 10, 14, 0, 0, 9, 9, 13,
32 1, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
33 13, 7, 5, 0, 0, 3, 3, 2, 14, 10, 14, 0, 0, 9, 9, 13
36 static uint8_t mnemonics[256][5] = {
37 "BRK ","ORA ","??? ","??? ","TSB ","ORA ","ASL ","RMB0",
38 "PHP ","ORA ","ASL ","??? ","TSB ","ORA ","ASL ","BBR0",
39 "BPL ","ORA ","ORA ","??? ","TRB ","ORA ","ASL ","RMB1",
40 "CLC ","ORA ","INC ","??? ","TRB ","ORA ","ASL ","BBR1",
41 "JSR ","AND ","??? ","??? ","BIT ","AND ","ROL ","RMB2",
42 "PLP ","AND ","ROL ","??? ","BIT ","AND ","ROL ","BBR2",
43 "BMI ","AND ","AND ","??? ","BIT ","AND ","ROL ","RMB3",
44 "SEC ","AND ","DEC ","??? ","BIT ","AND ","ROL ","BBR3",
45 "RTI ","EOR ","??? ","??? ","??? ","EOR ","LSR ","RMB4",
46 "PHA ","EOR ","LSR ","??? ","JMP ","EOR ","LSR ","BBR4",
47 "BVC ","EOR ","EOR ","??? ","??? ","EOR ","LSR ","RMB5",
48 "CLI ","EOR ","PHY ","??? ","??? ","EOR ","LSR ","BBR5",
49 "RTS ","ADC ","??? ","??? ","STZ ","ADC ","ROR ","RMB6",
50 "PLA ","ADC ","ROR ","??? ","JMP ","ADC ","ROR ","BBR6",
51 "BVS ","ADC ","ADC ","??? ","STZ ","ADC ","ROR ","RMB7",
52 "SEI ","ADC ","PLY ","??? ","JMP ","ADC ","ROR ","BBR7",
53 "BRA ","STA ","??? ","??? ","STY ","STA ","STX ","SMB0",
54 "DEY ","BIT ","TXA ","??? ","STY ","STA ","STX ","BBS0",
55 "BCC ","STA ","STA ","??? ","STY ","STA ","STX ","SMB1",
56 "TYA ","STA ","TXS ","??? ","STZ ","STA ","STZ ","BBS1",
57 "LDY ","LDA ","LDX ","??? ","LDY ","LDA ","LDX ","SMB2",
58 "TAY ","LDA ","TAX ","??? ","LDY ","LDA ","LDX ","BBS2",
59 "BCS ","LDA ","LDA ","??? ","LDY ","LDA ","LDX ","SMB3",
60 "CLV ","LDA ","TSX ","??? ","LDY ","LDA ","LDX ","BBS3",
61 "CPY ","CMP ","??? ","??? ","CPY ","CMP ","DEC ","SMB4",
62 "INY ","CMP ","DEX ","??? ","CPY ","CMP ","DEC ","BBS4",
63 "BNE ","CMP ","CMP ","??? ","??? ","CMP ","DEC ","SMB5",
64 "CLD ","CMP ","PHX ","??? ","??? ","CMP ","DEC ","BBS5",
65 "CPX ","SBC ","??? ","??? ","CPX ","SBC ","INC ","SMB6",
66 "INX ","SBC ","NOP ","??? ","CPX ","SBC ","INC ","BBS6",
67 "BEQ ","SBC ","SBC ","??? ","??? ","SBC ","INC ","SMB7",
68 "SED ","SBC ","PLX ","??? ","??? ","SBC ","INC ","BBS7"
73 // Display bytes in mem in hex
75 static void DisplayBytes(V65C02REGS * regs, char * outbuf, uint16_t src, uint32_t dst)
78 sprintf(outbuf, "%04X: ", src);
81 // That should fix the $FFFF bug...
85 for(uint32_t i=src; i<dst; i++)
87 sprintf(buf, "%02X ", regs->RdMem(i));
92 // Pad the leftover spaces...
93 for(int i=cnt; i<3; i++)
102 // Decode a 65C02 instruction
104 int Decode65C02(V65C02REGS * regs, char * outbuf, uint16_t pc)
106 char buf[32], buf2[32];
110 uint8_t opcode = regs->RdMem(addr++); // Get the opcode
112 switch (op_mat[opcode]) // Decode the addressing mode...
118 sprintf(buf, "%s #$%02X", mnemonics[opcode], regs->RdMem(addr++));
121 sprintf(buf, "%s $%02X", mnemonics[opcode], regs->RdMem(addr++));
123 case 3: // Zero page, X
124 sprintf(buf, "%s $%02X,X", mnemonics[opcode], regs->RdMem(addr++));
126 case 4: // Zero page, Y
127 sprintf(buf, "%s $%02X,Y", mnemonics[opcode], regs->RdMem(addr++));
129 case 5: // Zero page indirect
130 sprintf(buf, "%s ($%02X)", mnemonics[opcode], regs->RdMem(addr++));
132 case 6: // Zero page, X indirect
133 sprintf(buf, "%s ($%02X,X)", mnemonics[opcode], regs->RdMem(addr++));
135 case 7: // Zero page, Y indirect
136 sprintf(buf, "%s ($%02X),Y", mnemonics[opcode], regs->RdMem(addr++));
139 w = regs->RdMem(addr++);
140 w |= regs->RdMem(addr++) << 8;
141 sprintf(buf, "%s $%04X", mnemonics[opcode], w);
143 case 9: // Absolute, X
144 w = regs->RdMem(addr++);
145 w |= regs->RdMem(addr++) << 8;
146 sprintf(buf, "%s $%04X,X", mnemonics[opcode], w);
148 case 10: // Absolute, Y
149 w = regs->RdMem(addr++);
150 w |= regs->RdMem(addr++) << 8;
151 sprintf(buf, "%s $%04X,Y", mnemonics[opcode], w);
154 w = regs->RdMem(addr++);
155 w |= regs->RdMem(addr++) << 8;
156 sprintf(buf, "%s ($%04X)", mnemonics[opcode], w);
158 case 12: // Indirect, X
159 w = regs->RdMem(addr++);
160 w |= regs->RdMem(addr++) << 8;
161 sprintf(buf, "%s ($%04X,X)", mnemonics[opcode], w);
164 sprintf(buf, "%s $%04X", mnemonics[opcode], addr + (int16_t)((int8_t)regs->RdMem(addr)) + 1);
168 sprintf(buf, "%s ", mnemonics[opcode]);
172 DisplayBytes(regs, buf2, pc, addr); // Show bytes
173 sprintf(outbuf, "%s %-14s", buf2, buf); // Display opcode & addressing, etc.