]> Shamusworld >> Repos - apple2/blob - src/dis65c02.cpp
Added floppy #2 saving, statistics to makefile.
[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         uint8_t opcode = mainCPU.RdMem(addr++);                         // Get the opcode
117
118         switch (op_mat[opcode])                                                         // Decode the addressing mode...
119         {
120         case 0:                                                                                         // Illegal
121                 sprintf(buf, "???");
122                 break;
123         case 1:                                                                                         // Immediate
124                 sprintf(buf, "%s #$%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
125                 break;
126         case 2:                                                                                         // Zero page
127                 sprintf(buf, "%s $%02X", mnemonics[opcode], mainCPU.RdMem(addr++));
128                 break;
129         case 3:                                                                                         // Zero page, X
130                 sprintf(buf, "%s $%02X,X", mnemonics[opcode], mainCPU.RdMem(addr++));
131                 break;
132         case 4:                                                                                         // Zero page, Y
133                 sprintf(buf, "%s $%02X,Y", mnemonics[opcode], mainCPU.RdMem(addr++));
134                 break;
135         case 5:                                                                                         // Zero page indirect
136                 sprintf(buf, "%s ($%02X)", mnemonics[opcode], mainCPU.RdMem(addr++));
137                 break;
138         case 6:                                                                                         // Zero page, X indirect
139                 sprintf(buf, "%s ($%02X,X)", mnemonics[opcode], mainCPU.RdMem(addr++));
140                 break;
141         case 7:                                                                                         // Zero page, Y indirect
142                 sprintf(buf, "%s ($%02X),Y", mnemonics[opcode], mainCPU.RdMem(addr++));
143                 break;
144         case 8:                                                                                         // Absolute
145                 sprintf(buf, "%s $%04X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
146                 break;
147         case 9:                                                                                         // Absolute, X
148                 sprintf(buf, "%s $%04X,X", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
149                 break;
150         case 10:                                                                                        // Absolute, Y
151                 sprintf(buf, "%s $%04X,Y", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
152                 break;
153         case 11:                                                                                        // Indirect
154                 sprintf(buf, "%s ($%04X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
155                 break;
156         case 12:                                                                                        // Indirect, X
157                 sprintf(buf, "%s ($%04X,X)", mnemonics[opcode], mainCPU.RdMem(addr++) | (mainCPU.RdMem(addr++) << 8));
158                 break;
159         case 13:                                                                                        // Relative
160                 sprintf(buf, "%s $%04X", mnemonics[opcode], addr + (int16_t)((int8_t)mainCPU.RdMem(addr)) + 1);
161                 addr++;
162                 break;
163         case 14:                                                                                        // Inherent
164                 sprintf(buf, "%s ", mnemonics[opcode]);
165                 break;
166         }
167
168         DisplayBytes(buf2, pc, addr);                                           // Show bytes
169 //      WriteLog("%-16s", outbuf);                                                      // Display opcode & addressing, etc.
170         sprintf(outbuf, "%s %-14s", buf2, buf);                         // Display opcode & addressing, etc.
171
172         return addr - pc;
173 }
174