2 // 65C02 disassembler
\r
4 // by James L. Hammons
\r
5 // (c) 2005 Underground Software
\r
10 #include "dis65c02.h"
\r
11 //#include "types.h"
\r
15 using namespace std;
\r
19 extern V65C02REGS mainCPU;//Hm. Shouldn't we pass this shit in?
\r
21 // Private globals variables
\r
23 static uint8 op_mat[256] = {
\r
24 14, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
25 13, 7, 5, 0, 2, 3, 3, 2, 14, 10, 14, 0, 8, 9, 9, 13,
\r
26 8, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
27 13, 7, 5, 0, 3, 3, 3, 2, 14, 10, 14, 0, 9, 9, 9, 13,
\r
28 14, 6, 0, 0, 0, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
29 13, 7, 5, 0, 0, 3, 3, 2, 14, 10, 14, 0, 0, 9, 9, 13,
\r
30 14, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 11, 8, 8, 13,
\r
31 13, 7, 5, 0, 3, 3, 3, 2, 14, 10, 14, 0, 12, 9, 9, 13,
\r
32 13, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
33 13, 7, 5, 0, 3, 3, 4, 2, 14, 10, 14, 0, 8, 9, 9, 13,
\r
34 1, 6, 1, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
35 13, 7, 5, 0, 3, 3, 4, 2, 14, 10, 14, 0, 9, 9, 10, 13,
\r
36 1, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
37 13, 7, 5, 0, 0, 3, 3, 2, 14, 10, 14, 0, 0, 9, 9, 13,
\r
38 1, 6, 0, 0, 2, 2, 2, 2, 14, 1, 14, 0, 8, 8, 8, 13,
\r
39 13, 7, 5, 0, 0, 3, 3, 2, 14, 10, 14, 0, 0, 9, 9, 13 };
\r
41 static uint8 mnemonics[256][6] = {
\r
42 "BRK ","ORA ","??? ","??? ","TSB ","ORA ","ASL ","RMB0 ",
\r
43 "PHP ","ORA ","ASL ","??? ","TSB ","ORA ","ASL ","BBR0 ",
\r
44 "BPL ","ORA ","ORA ","??? ","TRB ","ORA ","ASL ","RMB1 ",
\r
45 "CLC ","ORA ","INC ","??? ","TRB ","ORA ","ASL ","BBR1 ",
\r
46 "JSR ","AND ","??? ","??? ","BIT ","AND ","ROL ","RMB2 ",
\r
47 "PLP ","AND ","ROL ","??? ","BIT ","AND ","ROL ","BBR2 ",
\r
48 "BMI ","AND ","AND ","??? ","BIT ","AND ","ROL ","RMB3 ",
\r
49 "SEC ","AND ","DEC ","??? ","BIT ","AND ","ROL ","BBR3 ",
\r
50 "RTI ","EOR ","??? ","??? ","??? ","EOR ","LSR ","RMB4 ",
\r
51 "PHA ","EOR ","LSR ","??? ","JMP ","EOR ","LSR ","BBR4 ",
\r
52 "BVC ","EOR ","EOR ","??? ","??? ","EOR ","LSR ","RMB5 ",
\r
53 "CLI ","EOR ","PHY ","??? ","??? ","EOR ","LSR ","BBR5 ",
\r
54 "RTS ","ADC ","??? ","??? ","STZ ","ADC ","ROR ","RMB6 ",
\r
55 "PLA ","ADC ","ROR ","??? ","JMP ","ADC ","ROR ","BBR6 ",
\r
56 "BVS ","ADC ","ADC ","??? ","STZ ","ADC ","ROR ","RMB7 ",
\r
57 "SEI ","ADC ","PLY ","??? ","JMP ","ADC ","ROR ","BBR7 ",
\r
58 "BRA ","STA ","??? ","??? ","STY ","STA ","STX ","SMB0 ",
\r
59 "DEY ","BIT ","TXA ","??? ","STY ","STA ","STX ","BBS0 ",
\r
60 "BCC ","STA ","STA ","??? ","STY ","STA ","STX ","SMB1 ",
\r
61 "TYA ","STA ","TXS ","??? ","STZ ","STA ","STZ ","BBS1 ",
\r
62 "LDY ","LDA ","LDX ","??? ","LDY ","LDA ","LDX ","SMB2 ",
\r
63 "TAY ","LDA ","TAX ","??? ","LDY ","LDA ","LDX ","BBS2 ",
\r
64 "BCS ","LDA ","LDA ","??? ","LDY ","LDA ","LDX ","SMB3 ",
\r
65 "CLV ","LDA ","TSX ","??? ","LDY ","LDA ","LDX ","BBS3 ",
\r
66 "CPY ","CMP ","??? ","??? ","CPY ","CMP ","DEC ","SMB4 ",
\r
67 "INY ","CMP ","DEX ","??? ","CPY ","CMP ","DEC ","BBS4 ",
\r
68 "BNE ","CMP ","CMP ","??? ","??? ","CMP ","DEC ","SMB5 ",
\r
69 "CLD ","CMP ","PHX ","??? ","??? ","CMP ","DEC ","BBS5 ",
\r
70 "CPX ","SBC ","??? ","??? ","CPX ","SBC ","INC ","SMB6 ",
\r
71 "INX ","SBC ","NOP ","??? ","CPX ","SBC ","INC ","BBS6 ",
\r
72 "BEQ ","SBC ","SBC ","??? ","??? ","SBC ","INC ","SMB7 ",
\r
73 "SED ","SBC ","PLX ","??? ","??? ","SBC ","INC ","BBS7 " };
\r
76 // Display bytes in mem in hex
\r
78 static void DisplayBytes(uint16 src, uint32 dst)
\r
80 WriteLog("%04X: ", src);
\r
81 uint8 cnt = 0; // Init counter...
\r
84 dst += 0x10000; // That should fix the FFFF bug...
\r
86 for(uint32 i=src; i<dst; i++)
\r
88 WriteLog("%02X ", mainCPU.RdMem(i));
\r
89 cnt++; // Bump counter...
\r
92 for(int i=cnt; i<5; i++) // Pad the leftover spaces...
\r
97 // Decode a 65C02 instruction
\r
99 int Decode65C02(uint16 pc)
\r
114 12) iax = ($0000,X)
\r
115 13) rel = $0000 (PC-relative)
\r
121 uint8 opcode = mainCPU.RdMem(addr++); // Get the opcode
\r
123 switch (op_mat[opcode]) // Decode the addressing mode...
\r
126 sprintf(outbuf, "???");
\r
128 case 1: // Immediate
\r
129 sprintf(outbuf, "%s #$%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
131 case 2: // Zero page
\r
132 sprintf(outbuf, "%s $%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
134 case 3: // Zero page, X
\r
135 sprintf(outbuf, "%s $%02X,X", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
137 case 4: // Zero page, Y
\r
138 sprintf(outbuf, "%s $%02X,Y", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
140 case 5: // Zero page indirect
\r
141 sprintf(outbuf, "%s ($%02X)", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
143 case 6: // Zero page, X indirect
\r
144 sprintf(outbuf, "%s ($%02X,X)", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
146 case 7: // Zero page, Y indirect
\r
147 sprintf(outbuf, "%s ($%02X),Y", mnemonics[opcode], mainCPU.RdMem(addr++));
\r
149 case 8: // Absolute
\r
150 sprintf(outbuf, "%s $%04X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
\r
152 case 9: // Absolute, X
\r
153 sprintf(outbuf, "%s $%04X,X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
\r
155 case 10: // Absolute, Y
\r
156 sprintf(outbuf, "%s $%04X,Y", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
\r
158 case 11: // Indirect
\r
159 sprintf(outbuf, "%s ($%04X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
\r
161 case 12: // Indirect, X
\r
162 sprintf(outbuf, "%s ($%04X,X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
\r
164 case 13: // Relative
\r
165 // sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16)(int8)mainCPU.RdMem(addr));
\r
166 sprintf(outbuf, "%s $%04X", mnemonics[opcode], addr + (int16)((int8)mainCPU.RdMem(addr)) + 1);
\r
169 case 14: // Inherent
\r
170 sprintf(outbuf, "%s ", mnemonics[opcode]);
\r
174 DisplayBytes(pc, addr); // Show bytes
\r
175 WriteLog("%-16s", outbuf); // Display opcode & addressing, etc.
\r