ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_6502.cpp
Revision: 1.5
Committed: 2000-09-25T12:44:31Z (24 years, 2 months ago) by cebix
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
- replaced 680x0 and 80x86 disassemblers with the ones from GNU binutils
- 680x0 disassembler shows symbolic MacOS low memory globals

File Contents

# Content
1 /*
2 * mon_6502.cpp - 6502 disassembler
3 *
4 * mon (C) 1997-2000 Christian Bauer, Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22
23 #include "mon.h"
24 #include "mon_disass.h"
25
26
27 // Addressing modes
28 enum {
29 A_IMPL,
30 A_ACCU, // A
31 A_IMM, // #zz
32 A_REL, // Branches
33 A_ZERO, // zz
34 A_ZEROX, // zz,x
35 A_ZEROY, // zz,y
36 A_ABS, // zzzz
37 A_ABSX, // zzzz,x
38 A_ABSY, // zzzz,y
39 A_IND, // (zzzz)
40 A_INDX, // (zz,x)
41 A_INDY // (zz),y
42 };
43
44 // Mnemonics
45 enum {
46 M_ADC, M_AND, M_ASL, M_BCC, M_BCS, M_BEQ, M_BIT, M_BMI, M_BNE, M_BPL,
47 M_BRK, M_BVC, M_BVS, M_CLC, M_CLD, M_CLI, M_CLV, M_CMP, M_CPX, M_CPY,
48 M_DEC, M_DEX, M_DEY, M_EOR, M_INC, M_INX, M_INY, M_JMP, M_JSR, M_LDA,
49 M_LDX, M_LDY, M_LSR, M_NOP, M_ORA, M_PHA, M_PHP, M_PLA, M_PLP, M_ROL,
50 M_ROR, M_RTI, M_RTS, M_SBC, M_SEC, M_SED, M_SEI, M_STA, M_STX, M_STY,
51 M_TAX, M_TAY, M_TSX, M_TXA, M_TXS, M_TYA,
52
53 M_ILLEGAL, // Undocumented opcodes start here
54
55 M_IANC, M_IANE, M_IARR, M_IASR, M_IDCP, M_IISB, M_IJAM, M_INOP, M_ILAS,
56 M_ILAX, M_ILXA, M_IRLA, M_IRRA, M_ISAX, M_ISBC, M_ISBX, M_ISHA, M_ISHS,
57 M_ISHX, M_ISHY, M_ISLO, M_ISRE,
58
59 M_MAXIMUM // Highest element
60 };
61
62 // Mnemonic for each opcode
63 static const char mnemonic[256] = {
64 M_BRK , M_ORA , M_IJAM, M_ISLO, M_INOP, M_ORA, M_ASL , M_ISLO, // 00
65 M_PHP , M_ORA , M_ASL , M_IANC, M_INOP, M_ORA, M_ASL , M_ISLO,
66 M_BPL , M_ORA , M_IJAM, M_ISLO, M_INOP, M_ORA, M_ASL , M_ISLO, // 10
67 M_CLC , M_ORA , M_INOP, M_ISLO, M_INOP, M_ORA, M_ASL , M_ISLO,
68 M_JSR , M_AND , M_IJAM, M_IRLA, M_BIT , M_AND, M_ROL , M_IRLA, // 20
69 M_PLP , M_AND , M_ROL , M_IANC, M_BIT , M_AND, M_ROL , M_IRLA,
70 M_BMI , M_AND , M_IJAM, M_IRLA, M_INOP, M_AND, M_ROL , M_IRLA, // 30
71 M_SEC , M_AND , M_INOP, M_IRLA, M_INOP, M_AND, M_ROL , M_IRLA,
72 M_RTI , M_EOR , M_IJAM, M_ISRE, M_INOP, M_EOR, M_LSR , M_ISRE, // 40
73 M_PHA , M_EOR , M_LSR , M_IASR, M_JMP , M_EOR, M_LSR , M_ISRE,
74 M_BVC , M_EOR , M_IJAM, M_ISRE, M_INOP, M_EOR, M_LSR , M_ISRE, // 50
75 M_CLI , M_EOR , M_INOP, M_ISRE, M_INOP, M_EOR, M_LSR , M_ISRE,
76 M_RTS , M_ADC , M_IJAM, M_IRRA, M_INOP, M_ADC, M_ROR , M_IRRA, // 60
77 M_PLA , M_ADC , M_ROR , M_IARR, M_JMP , M_ADC, M_ROR , M_IRRA,
78 M_BVS , M_ADC , M_IJAM, M_IRRA, M_INOP, M_ADC, M_ROR , M_IRRA, // 70
79 M_SEI , M_ADC , M_INOP, M_IRRA, M_INOP, M_ADC, M_ROR , M_IRRA,
80 M_INOP, M_STA , M_INOP, M_ISAX, M_STY , M_STA, M_STX , M_ISAX, // 80
81 M_DEY , M_INOP, M_TXA , M_IANE, M_STY , M_STA, M_STX , M_ISAX,
82 M_BCC , M_STA , M_IJAM, M_ISHA, M_STY , M_STA, M_STX , M_ISAX, // 90
83 M_TYA , M_STA , M_TXS , M_ISHS, M_ISHY, M_STA, M_ISHX, M_ISHA,
84 M_LDY , M_LDA , M_LDX , M_ILAX, M_LDY , M_LDA, M_LDX , M_ILAX, // a0
85 M_TAY , M_LDA , M_TAX , M_ILXA, M_LDY , M_LDA, M_LDX , M_ILAX,
86 M_BCS , M_LDA , M_IJAM, M_ILAX, M_LDY , M_LDA, M_LDX , M_ILAX, // b0
87 M_CLV , M_LDA , M_TSX , M_ILAS, M_LDY , M_LDA, M_LDX , M_ILAX,
88 M_CPY , M_CMP , M_INOP, M_IDCP, M_CPY , M_CMP, M_DEC , M_IDCP, // c0
89 M_INY , M_CMP , M_DEX , M_ISBX, M_CPY , M_CMP, M_DEC , M_IDCP,
90 M_BNE , M_CMP , M_IJAM, M_IDCP, M_INOP, M_CMP, M_DEC , M_IDCP, // d0
91 M_CLD , M_CMP , M_INOP, M_IDCP, M_INOP, M_CMP, M_DEC , M_IDCP,
92 M_CPX , M_SBC , M_INOP, M_IISB, M_CPX , M_SBC, M_INC , M_IISB, // e0
93 M_INX , M_SBC , M_NOP , M_ISBC, M_CPX , M_SBC, M_INC , M_IISB,
94 M_BEQ , M_SBC , M_IJAM, M_IISB, M_INOP, M_SBC, M_INC , M_IISB, // f0
95 M_SED , M_SBC , M_INOP, M_IISB, M_INOP, M_SBC, M_INC , M_IISB
96 };
97
98 // Addressing mode for each opcode
99 static const char adr_mode[256] = {
100 A_IMPL, A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 00
101 A_IMPL, A_IMM , A_ACCU, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
102 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 10
103 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
104 A_ABS , A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 20
105 A_IMPL, A_IMM , A_ACCU, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
106 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 30
107 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
108 A_IMPL, A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 40
109 A_IMPL, A_IMM , A_ACCU, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
110 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 50
111 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
112 A_IMPL, A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 60
113 A_IMPL, A_IMM , A_ACCU, A_IMM , A_IND , A_ABS , A_ABS , A_ABS,
114 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 70
115 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
116 A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 80
117 A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
118 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROY, A_ZEROY, // 90
119 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSY , A_ABSY,
120 A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // a0
121 A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
122 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROY, A_ZEROY, // b0
123 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSY , A_ABSY,
124 A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // c0
125 A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
126 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // d0
127 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
128 A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // e0
129 A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
130 A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // f0
131 A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX
132 };
133
134 // Chars for each mnemonic
135 static const char mnem_1[] = "aaabbbbbbbbbbcccccccdddeiiijjllllnopppprrrrssssssstttttt?aaaadijnlllrrsssssssss";
136 static const char mnem_2[] = "dnscceimnprvvllllmppeeeonnnmsdddsorhhlloottbeeetttaasxxy?nnrscsaoaaxlrabbhhhhlr";
137 static const char mnem_3[] = "cdlcsqtielkcscdivpxycxyrcxypraxyrpaapaplrisccdiaxyxyxasa?cerrpbmpsxaaaxcxasxyoe";
138
139 // Instruction length for each addressing mode
140 static const char adr_length[] = {1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2};
141
142
143 /*
144 * Disassemble one instruction, return number of bytes
145 */
146
147 int disass_6502(FILE *f, uint32 adr, uint8 op, uint8 lo, uint8 hi)
148 {
149 char mode = adr_mode[op], mnem = mnemonic[op];
150
151 // Display instruction bytes in hex
152 switch (adr_length[mode]) {
153 case 1:
154 fprintf(f, "%02x\t\t", op);
155 break;
156
157 case 2:
158 fprintf(f, "%02x %02x\t\t", op, lo);
159 break;
160
161 case 3:
162 fprintf(f, "%02x %02x %02x\t", op, lo, hi);
163 break;
164 }
165
166 // Tag undocumented opcodes with an asterisk
167 if (mnem > M_ILLEGAL)
168 fputc('*', f);
169 else
170 fputc(' ', f);
171
172 // Print mnemonic
173 fprintf(f, "%c%c%c ", mnem_1[mnem], mnem_2[mnem], mnem_3[mnem]);
174
175 // Print argument
176 switch (mode) {
177 case A_IMPL:
178 break;
179
180 case A_ACCU:
181 fprintf(f, "a");
182 break;
183
184 case A_IMM:
185 fprintf(f, "#$%02x", lo);
186 break;
187
188 case A_REL:
189 fprintf(f, "$%04x", (adr + 2) + (int8)lo);
190 break;
191
192 case A_ZERO:
193 fprintf(f, "$%02x", lo);
194 break;
195
196 case A_ZEROX:
197 fprintf(f, "$%02x,x", lo);
198 break;
199
200 case A_ZEROY:
201 fprintf(f, "$%02x,y", lo);
202 break;
203
204 case A_ABS:
205 fprintf(f, "$%04x", (hi << 8) | lo);
206 break;
207
208 case A_ABSX:
209 fprintf(f, "$%04x,x", (hi << 8) | lo);
210 break;
211
212 case A_ABSY:
213 fprintf(f, "$%04x,y", (hi << 8) | lo);
214 break;
215
216 case A_IND:
217 fprintf(f, "($%04x)", (hi << 8) | lo);
218 break;
219
220 case A_INDX:
221 fprintf(f, "($%02x,x)", lo);
222 break;
223
224 case A_INDY:
225 fprintf(f, "($%02x),y", lo);
226 break;
227 }
228
229 fputc('\n', f);
230 return adr_length[mode];
231 }