]> Shamusworld >> Repos - apple2/blob - src/dis65c02.cpp
f8052e2b72ee4334a14ce4b75e94a941b5165750
[apple2] / src / dis65c02.cpp
1 //
2 // 65C02 disassembler
3 //
4 // by James L. Hammons
5 // (c) 2005 Underground Software
6 //
7
8 #include "dis65c02.h"
9
10 #include <stdio.h>
11 #include <string>
12 #include "v65c02.h"
13 #include "log.h"
14
15 using namespace std;
16
17 // External shit
18
19 extern V65C02REGS mainCPU;//Hm. Shouldn't we pass this shit in? ANSWER: YES. !!! FIX !!!
20
21 // Private globals variables
22
23 static uint8 op_mat[256] = {
24         14, 6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
25         13, 7,  5,  0,  2,  3,  3,  2,  14, 10, 14, 0,  8,  9,  9,  13,
26         8,  6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
27         13, 7,  5,  0,  3,  3,  3,  2,  14, 10, 14, 0,  9,  9,  9,  13,
28         14, 6,  0,  0,  0,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
29         13, 7,  5,  0,  0,  3,  3,  2,  14, 10, 14, 0,  0,  9,  9,  13,
30         14, 6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  11, 8,  8,  13,
31         13, 7,  5,  0,  3,  3,  3,  2,  14, 10, 14, 0,  12, 9,  9,  13,
32         13, 6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
33         13, 7,  5,  0,  3,  3,  4,  2,  14, 10, 14, 0,  8,  9,  9,  13,
34         1,  6,  1,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
35         13, 7,  5,  0,  3,  3,  4,  2,  14, 10, 14, 0,  9,  9,  10, 13,
36         1,  6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
37         13, 7,  5,  0,  0,  3,  3,  2,  14, 10, 14, 0,  0,  9,  9,  13,
38         1,  6,  0,  0,  2,  2,  2,  2,  14, 1,  14, 0,  8,  8,  8,  13,
39         13, 7,  5,  0,  0,  3,  3,  2,  14, 10, 14, 0,  0,  9,  9,  13  };
40
41 static uint8 mnemonics[256][6] = {
42         "BRK  ","ORA  ","???  ","???  ","TSB  ","ORA  ","ASL  ","RMB0 ",
43         "PHP  ","ORA  ","ASL  ","???  ","TSB  ","ORA  ","ASL  ","BBR0 ",
44         "BPL  ","ORA  ","ORA  ","???  ","TRB  ","ORA  ","ASL  ","RMB1 ",
45         "CLC  ","ORA  ","INC  ","???  ","TRB  ","ORA  ","ASL  ","BBR1 ",
46         "JSR  ","AND  ","???  ","???  ","BIT  ","AND  ","ROL  ","RMB2 ",
47         "PLP  ","AND  ","ROL  ","???  ","BIT  ","AND  ","ROL  ","BBR2 ",
48         "BMI  ","AND  ","AND  ","???  ","BIT  ","AND  ","ROL  ","RMB3 ",
49         "SEC  ","AND  ","DEC  ","???  ","BIT  ","AND  ","ROL  ","BBR3 ",
50         "RTI  ","EOR  ","???  ","???  ","???  ","EOR  ","LSR  ","RMB4 ",
51         "PHA  ","EOR  ","LSR  ","???  ","JMP  ","EOR  ","LSR  ","BBR4 ",
52         "BVC  ","EOR  ","EOR  ","???  ","???  ","EOR  ","LSR  ","RMB5 ",
53         "CLI  ","EOR  ","PHY  ","???  ","???  ","EOR  ","LSR  ","BBR5 ",
54         "RTS  ","ADC  ","???  ","???  ","STZ  ","ADC  ","ROR  ","RMB6 ",
55         "PLA  ","ADC  ","ROR  ","???  ","JMP  ","ADC  ","ROR  ","BBR6 ",
56         "BVS  ","ADC  ","ADC  ","???  ","STZ  ","ADC  ","ROR  ","RMB7 ",
57         "SEI  ","ADC  ","PLY  ","???  ","JMP  ","ADC  ","ROR  ","BBR7 ",
58         "BRA  ","STA  ","???  ","???  ","STY  ","STA  ","STX  ","SMB0 ",
59         "DEY  ","BIT  ","TXA  ","???  ","STY  ","STA  ","STX  ","BBS0 ",
60         "BCC  ","STA  ","STA  ","???  ","STY  ","STA  ","STX  ","SMB1 ",
61         "TYA  ","STA  ","TXS  ","???  ","STZ  ","STA  ","STZ  ","BBS1 ",
62         "LDY  ","LDA  ","LDX  ","???  ","LDY  ","LDA  ","LDX  ","SMB2 ",
63         "TAY  ","LDA  ","TAX  ","???  ","LDY  ","LDA  ","LDX  ","BBS2 ",
64         "BCS  ","LDA  ","LDA  ","???  ","LDY  ","LDA  ","LDX  ","SMB3 ",
65         "CLV  ","LDA  ","TSX  ","???  ","LDY  ","LDA  ","LDX  ","BBS3 ",
66         "CPY  ","CMP  ","???  ","???  ","CPY  ","CMP  ","DEC  ","SMB4 ",
67         "INY  ","CMP  ","DEX  ","???  ","CPY  ","CMP  ","DEC  ","BBS4 ",
68         "BNE  ","CMP  ","CMP  ","???  ","???  ","CMP  ","DEC  ","SMB5 ",
69         "CLD  ","CMP  ","PHX  ","???  ","???  ","CMP  ","DEC  ","BBS5 ",
70         "CPX  ","SBC  ","???  ","???  ","CPX  ","SBC  ","INC  ","SMB6 ",
71         "INX  ","SBC  ","NOP  ","???  ","CPX  ","SBC  ","INC  ","BBS6 ",
72         "BEQ  ","SBC  ","SBC  ","???  ","???  ","SBC  ","INC  ","SMB7 ",
73         "SED  ","SBC  ","PLX  ","???  ","???  ","SBC  ","INC  ","BBS7 " };
74
75 //
76 // Display bytes in mem in hex
77 //
78 static void DisplayBytes(uint16 src, uint32 dst)
79 {
80         WriteLog("%04X: ", src);
81         uint8 cnt = 0;                                                                          // Init counter...
82
83         if (src > dst)
84                 dst += 0x10000;                                                                 // That should fix the FFFF bug...
85
86         for(uint32 i=src; i<dst; i++)
87         {
88                 WriteLog("%02X ", mainCPU.RdMem(i));
89                 cnt++;                                                                                  // Bump counter...
90         }
91
92         for(int i=cnt; i<5; i++)                                                        // Pad the leftover spaces...
93                 WriteLog("   ");
94 }
95
96 //
97 // Decode a 65C02 instruction
98 //
99 int Decode65C02(uint16 pc)
100 {
101 /*
102  0) illegal
103  1) imm = #$00
104  2) zp = $00
105  3) zpx = $00,X
106  4) zpy = $00,Y
107  5) izp = ($00)
108  6) izx = ($00,X)
109  7) izy = ($00),Y
110  8) abs = $0000
111  9) abx = $0000,X
112 10) aby = $0000,Y
113 11) ind = ($0000)
114 12) iax = ($0000,X)
115 13) rel = $0000 (PC-relative)
116 14) inherent
117 */
118         char outbuf[80];
119
120         uint16 addr = pc;
121         uint8 opcode = mainCPU.RdMem(addr++);                           // Get the opcode
122
123         switch (op_mat[opcode])                                                         // Decode the addressing mode...
124         {
125         case 0:                                                                                         // Illegal
126                 sprintf(outbuf, "???");
127                 break;
128         case 1:                                                                                         // Immediate
129                 sprintf(outbuf, "%s #$%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
130                 break;
131         case 2:                                                                                         // Zero page
132                 sprintf(outbuf, "%s $%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
133                 break;
134         case 3:                                                                                         // Zero page, X
135                 sprintf(outbuf, "%s $%02X,X", mnemonics[opcode], mainCPU.RdMem(addr++));
136                 break;
137         case 4:                                                                                         // Zero page, Y
138                 sprintf(outbuf, "%s $%02X,Y", mnemonics[opcode], mainCPU.RdMem(addr++));
139                 break;
140         case 5:                                                                                         // Zero page indirect
141                 sprintf(outbuf, "%s ($%02X)", mnemonics[opcode], mainCPU.RdMem(addr++));
142                 break;
143         case 6:                                                                                         // Zero page, X indirect
144                 sprintf(outbuf, "%s ($%02X,X)", mnemonics[opcode], mainCPU.RdMem(addr++));
145                 break;
146         case 7:                                                                                         // Zero page, Y indirect
147                 sprintf(outbuf, "%s ($%02X),Y", mnemonics[opcode], mainCPU.RdMem(addr++));
148                 break;
149         case 8:                                                                                         // Absolute
150                 sprintf(outbuf, "%s $%04X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
151                 break;
152         case 9:                                                                                         // Absolute, X
153                 sprintf(outbuf, "%s $%04X,X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
154                 break;
155         case 10:                                                                                        // Absolute, Y
156                 sprintf(outbuf, "%s $%04X,Y", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
157                 break;
158         case 11:                                                                                        // Indirect
159                 sprintf(outbuf, "%s ($%04X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
160                 break;
161         case 12:                                                                                        // Indirect, X
162                 sprintf(outbuf, "%s ($%04X,X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
163                 break;
164         case 13:                                                                                        // Relative
165 //              sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16)(int8)mainCPU.RdMem(addr));
166                 sprintf(outbuf, "%s $%04X", mnemonics[opcode], addr + (int16)((int8)mainCPU.RdMem(addr)) + 1);
167                 addr++;
168                 break;
169         case 14:                                                                                        // Inherent
170                 sprintf(outbuf, "%s ", mnemonics[opcode]);
171                 break;
172         }
173
174         DisplayBytes(pc, addr);                                                         // Show bytes
175         WriteLog("%-16s", outbuf);                                                      // Display opcode & addressing, etc.
176
177         return addr - pc;
178 }