ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_6502.cpp
Revision: 1.10
Committed: 2007-01-21T17:32:05Z (17 years, 10 months ago) by cebix
Branch: MAIN
CVS Tags: release_3-2, HEAD
Changes since 1.9: +7 -6 lines
Log Message:
fixed compiler warnings

File Contents

# Content
1 /*
2 * mon_6502.cpp - 6502 disassembler
3 *
4 * cxmon (C) 1997-2004 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 AddrMode {
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 Mnemonic {
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 Mnemonic 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 AddrMode 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 int 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 AddrMode mode = adr_mode[op];
150 Mnemonic mnem = mnemonic[op];
151
152 // Display instruction bytes in hex
153 switch (adr_length[mode]) {
154 case 1:
155 fprintf(f, "%02x\t\t", op);
156 break;
157
158 case 2:
159 fprintf(f, "%02x %02x\t\t", op, lo);
160 break;
161
162 case 3:
163 fprintf(f, "%02x %02x %02x\t", op, lo, hi);
164 break;
165 }
166
167 // Tag undocumented opcodes with an asterisk
168 if (mnem > M_ILLEGAL)
169 fputc('*', f);
170 else
171 fputc(' ', f);
172
173 // Print mnemonic
174 fprintf(f, "%c%c%c ", mnem_1[mnem], mnem_2[mnem], mnem_3[mnem]);
175
176 // Print argument
177 switch (mode) {
178 case A_IMPL:
179 break;
180
181 case A_ACCU:
182 fprintf(f, "a");
183 break;
184
185 case A_IMM:
186 fprintf(f, "#$%02x", lo);
187 break;
188
189 case A_REL:
190 fprintf(f, "$%04x", (adr + 2) + (int8)lo);
191 break;
192
193 case A_ZERO:
194 fprintf(f, "$%02x", lo);
195 break;
196
197 case A_ZEROX:
198 fprintf(f, "$%02x,x", lo);
199 break;
200
201 case A_ZEROY:
202 fprintf(f, "$%02x,y", lo);
203 break;
204
205 case A_ABS:
206 fprintf(f, "$%04x", (hi << 8) | lo);
207 break;
208
209 case A_ABSX:
210 fprintf(f, "$%04x,x", (hi << 8) | lo);
211 break;
212
213 case A_ABSY:
214 fprintf(f, "$%04x,y", (hi << 8) | lo);
215 break;
216
217 case A_IND:
218 fprintf(f, "($%04x)", (hi << 8) | lo);
219 break;
220
221 case A_INDX:
222 fprintf(f, "($%02x,x)", lo);
223 break;
224
225 case A_INDY:
226 fprintf(f, "($%02x),y", lo);
227 break;
228 }
229
230 fputc('\n', f);
231 return adr_length[mode];
232 }