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