]> Shamusworld >> Repos - apple2/blob - apple2/src/dis65c02.cpp
61976597126b9ec00848b3da5c5c7e2c473c9d94
[apple2] / apple2 / src / dis65c02.cpp
1 //\r
2 // 65C02 disassembler\r
3 //\r
4 // by James L. Hammons\r
5 // (c) 2005 Underground Software\r
6 //\r
7 \r
8 #include <stdio.h>\r
9 #include <string>\r
10 #include "dis65c02.h"\r
11 //#include "types.h"\r
12 #include "v65c02.h"\r
13 #include "log.h"\r
14 \r
15 using namespace std;\r
16 \r
17 // External shit\r
18 \r
19 extern V65C02REGS mainCPU;//Hm. Shouldn't we pass this shit in?\r
20 \r
21 // Private globals variables\r
22 \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
40 \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
74 \r
75 //\r
76 // Display bytes in mem in hex\r
77 //\r
78 static void DisplayBytes(uint16 src, uint32 dst)\r
79 {\r
80         WriteLog("%04X: ", src);\r
81         uint8 cnt = 0;                                                                          // Init counter...\r
82 \r
83         if (src > dst)\r
84                 dst += 0x10000;                                                                 // That should fix the FFFF bug...\r
85 \r
86         for(uint32 i=src; i<dst; i++)\r
87         {\r
88                 WriteLog("%02X ", mainCPU.RdMem(i));\r
89                 cnt++;                                                                                  // Bump counter...\r
90         }\r
91 \r
92         for(int i=cnt; i<5; i++)                                                        // Pad the leftover spaces...\r
93                 WriteLog("   ");\r
94 }\r
95 \r
96 //\r
97 // Decode a 65C02 instruction\r
98 //\r
99 int Decode65C02(uint16 pc)\r
100 {\r
101 /*\r
102  0) illegal\r
103  1) imm = #$00\r
104  2) zp = $00\r
105  3) zpx = $00,X\r
106  4) zpy = $00,Y\r
107  5) izp = ($00)\r
108  6) izx = ($00,X)\r
109  7) izy = ($00),Y\r
110  8) abs = $0000\r
111  9) abx = $0000,X\r
112 10) aby = $0000,Y\r
113 11) ind = ($0000)\r
114 12) iax = ($0000,X)\r
115 13) rel = $0000 (PC-relative)\r
116 14) inherent\r
117 */\r
118         char outbuf[80];\r
119 \r
120         uint16 addr = pc;\r
121         uint8 opcode = mainCPU.RdMem(addr++);                           // Get the opcode\r
122 \r
123         switch (op_mat[opcode])                                                         // Decode the addressing mode...\r
124         {\r
125         case 0:                                                                                         // Illegal\r
126                 sprintf(outbuf, "???");\r
127                 break;\r
128         case 1:                                                                                         // Immediate\r
129                 sprintf(outbuf, "%s #$%02X", mnemonics[opcode], mainCPU.RdMem(addr++));\r
130                 break;\r
131         case 2:                                                                                         // Zero page\r
132                 sprintf(outbuf, "%s $%02X", mnemonics[opcode], mainCPU.RdMem(addr++));\r
133                 break;\r
134         case 3:                                                                                         // Zero page, X\r
135                 sprintf(outbuf, "%s $%02X,X", mnemonics[opcode], mainCPU.RdMem(addr++));\r
136                 break;\r
137         case 4:                                                                                         // Zero page, Y\r
138                 sprintf(outbuf, "%s $%02X,Y", mnemonics[opcode], mainCPU.RdMem(addr++));\r
139                 break;\r
140         case 5:                                                                                         // Zero page indirect\r
141                 sprintf(outbuf, "%s ($%02X)", mnemonics[opcode], mainCPU.RdMem(addr++));\r
142                 break;\r
143         case 6:                                                                                         // Zero page, X indirect\r
144                 sprintf(outbuf, "%s ($%02X,X)", mnemonics[opcode], mainCPU.RdMem(addr++));\r
145                 break;\r
146         case 7:                                                                                         // Zero page, Y indirect\r
147                 sprintf(outbuf, "%s ($%02X),Y", mnemonics[opcode], mainCPU.RdMem(addr++));\r
148                 break;\r
149         case 8:                                                                                         // Absolute\r
150                 sprintf(outbuf, "%s $%04X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));\r
151                 break;\r
152         case 9:                                                                                         // Absolute, X\r
153                 sprintf(outbuf, "%s $%04X,X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));\r
154                 break;\r
155         case 10:                                                                                        // Absolute, Y\r
156                 sprintf(outbuf, "%s $%04X,Y", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));\r
157                 break;\r
158         case 11:                                                                                        // Indirect\r
159                 sprintf(outbuf, "%s ($%04X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));\r
160                 break;\r
161         case 12:                                                                                        // Indirect, X\r
162                 sprintf(outbuf, "%s ($%04X,X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));\r
163                 break;\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
167                 addr++;\r
168                 break;\r
169         case 14:                                                                                        // Inherent\r
170                 sprintf(outbuf, "%s ", mnemonics[opcode]);\r
171                 break;\r
172         }\r
173 \r
174         DisplayBytes(pc, addr);                                                         // Show bytes\r
175         WriteLog("%-16s", outbuf);                                                      // Display opcode & addressing, etc.\r
176 \r
177         return addr - pc;\r
178 }\r