fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/e6502/disasm.c *
7 * Created: 2004-05-25 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2004-2022 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include <string.h>
24
25#include "e6502.h"
26#include "internal.h"
27
28
29#define E6502_MODE_IMP 1
30#define E6502_MODE_IMM 2
31#define E6502_MODE_ZPG 3
32#define E6502_MODE_ZPG_X 4
33#define E6502_MODE_ZPG_Y 5
34#define E6502_MODE_ABS 6
35#define E6502_MODE_ABS_Y 7
36#define E6502_MODE_ABS_X 8
37#define E6502_MODE_IDX_IND_X 9
38#define E6502_MODE_IND_IDX_Y 10
39#define E6502_MODE_DB 11
40#define E6502_MODE_BRA 12
41#define E6502_MODE_JMP 13
42#define E6502_MODE_A 14
43
44
45typedef struct {
46 unsigned char opcode;
47 const char *mnemonic;
48 unsigned char mode;
49 unsigned char size;
50 unsigned char cycles;
51 unsigned flags;
52} e6502_dop_t;
53
54static
55e6502_dop_t doptab[256] = {
56 { 0x00, "BRK", E6502_MODE_IMP, 1, 7, 0 },
57 { 0x01, "ORA", E6502_MODE_IDX_IND_X, 2, 6, 0 },
58 { 0x02, "DB", E6502_MODE_DB, 1, 1, 0 },
59 { 0x03, "SLO", E6502_MODE_IDX_IND_X, 2, 8, E6502_OPF_UND },
60 { 0x04, "NOP", E6502_MODE_ZPG, 2, 3, E6502_OPF_UND },
61 { 0x05, "ORA", E6502_MODE_ZPG, 2, 3, 0 },
62 { 0x06, "ASL", E6502_MODE_ZPG, 2, 5, 0 },
63 { 0x07, "SLO", E6502_MODE_ZPG, 2, 5, E6502_OPF_UND },
64 { 0x08, "PHP", E6502_MODE_IMP, 1, 3, 0 },
65 { 0x09, "ORA", E6502_MODE_IMM, 2, 2, 0 },
66 { 0x0a, "ASL", E6502_MODE_A, 1, 2, 0 },
67 { 0x0b, "DB", E6502_MODE_DB, 1, 1, 0 },
68 { 0x0c, "NOP", E6502_MODE_ABS, 3, 4, E6502_OPF_UND },
69 { 0x0d, "ORA", E6502_MODE_ABS, 3, 4, 0 },
70 { 0x0e, "ASL", E6502_MODE_ABS, 3, 6, 0 },
71 { 0x0f, "SLO", E6502_MODE_ABS, 3, 6, E6502_OPF_UND },
72 { 0x10, "BPL", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
73 { 0x11, "ORA", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
74 { 0x12, "DB", E6502_MODE_DB, 1, 1, 0 },
75 { 0x13, "SLO", E6502_MODE_IND_IDX_Y, 2, 8, E6502_OPF_UND },
76 { 0x14, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND },
77 { 0x15, "ORA", E6502_MODE_ZPG_X, 2, 4, 0 },
78 { 0x16, "ASL", E6502_MODE_ZPG_X, 2, 6, 0 },
79 { 0x17, "SLO", E6502_MODE_ZPG_X, 2, 6, E6502_OPF_UND },
80 { 0x18, "CLC", E6502_MODE_IMP, 1, 2, 0 },
81 { 0x19, "ORA", E6502_MODE_ABS_Y, 3, 4, 0 },
82 { 0x1a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND },
83 { 0x1b, "SLO", E6502_MODE_ABS_Y, 3, 7, E6502_OPF_UND },
84 { 0x1c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND },
85 { 0x1d, "ORA", E6502_MODE_ABS_X, 3, 4, 0 },
86 { 0x1e, "ASL", E6502_MODE_ABS_X, 3, 7, 0 },
87 { 0x1f, "SLO", E6502_MODE_ABS_X, 3, 7, E6502_OPF_UND },
88 { 0x20, "JSR", E6502_MODE_JMP, 3, 6, E6502_OPF_JSR },
89 { 0x21, "AND", E6502_MODE_IDX_IND_X, 2, 6, 0 },
90 { 0x22, "DB", E6502_MODE_DB, 1, 1, 0 },
91 { 0x23, "RLA", E6502_MODE_IDX_IND_X, 2, 8, E6502_OPF_UND },
92 { 0x24, "BIT", E6502_MODE_ZPG, 2, 3, 0 },
93 { 0x25, "AND", E6502_MODE_ZPG, 2, 3, 0 },
94 { 0x26, "ROL", E6502_MODE_ZPG, 2, 5, 0 },
95 { 0x27, "RLA", E6502_MODE_ZPG, 2, 5, E6502_OPF_UND },
96 { 0x28, "PLP", E6502_MODE_IMP, 1, 4, 0 },
97 { 0x29, "AND", E6502_MODE_IMM, 2, 2, 0 },
98 { 0x2a, "ROL", E6502_MODE_A, 1, 2, 0 },
99 { 0x2b, "DB", E6502_MODE_DB, 1, 1, 0 },
100 { 0x2c, "BIT", E6502_MODE_ABS, 3, 4, 0 },
101 { 0x2d, "AND", E6502_MODE_ABS, 3, 4, 0 },
102 { 0x2e, "ROL", E6502_MODE_ABS, 3, 6, 0 },
103 { 0x2f, "RLA", E6502_MODE_ABS, 3, 6, E6502_OPF_UND },
104 { 0x30, "BMI", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
105 { 0x31, "AND", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
106 { 0x32, "DB", E6502_MODE_DB, 1, 1, 0 },
107 { 0x33, "RLA", E6502_MODE_IND_IDX_Y, 2, 8, E6502_OPF_UND },
108 { 0x34, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND },
109 { 0x35, "AND", E6502_MODE_ZPG_X, 2, 4, 0 },
110 { 0x36, "ROL", E6502_MODE_ZPG_X, 2, 6, 0 },
111 { 0x37, "RLA", E6502_MODE_ZPG_X, 2, 6, E6502_OPF_UND },
112 { 0x38, "SEC", E6502_MODE_IMP, 1, 2, 0 },
113 { 0x39, "AND", E6502_MODE_ABS_Y, 3, 4, 0 },
114 { 0x3a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND },
115 { 0x3b, "RLA", E6502_MODE_ABS_Y, 3, 7, E6502_OPF_UND },
116 { 0x3c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND },
117 { 0x3d, "AND", E6502_MODE_ABS_X, 3, 4, 0 },
118 { 0x3e, "ROL", E6502_MODE_ABS_X, 3, 7, 0 },
119 { 0x3f, "RLA", E6502_MODE_ABS_X, 3, 7, E6502_OPF_UND },
120 { 0x40, "RTI", E6502_MODE_IMP, 1, 6, E6502_OPF_RTI },
121 { 0x41, "EOR", E6502_MODE_IDX_IND_X, 2, 6, 0 },
122 { 0x42, "DB", E6502_MODE_DB, 1, 1, 0 },
123 { 0x43, "SRE", E6502_MODE_IDX_IND_X, 2, 8, E6502_OPF_UND },
124 { 0x44, "NOP", E6502_MODE_ZPG, 2, 3, E6502_OPF_UND },
125 { 0x45, "EOR", E6502_MODE_ZPG, 2, 3, 0 },
126 { 0x46, "LSR", E6502_MODE_ZPG, 2, 5, 0 },
127 { 0x47, "SRE", E6502_MODE_ZPG, 2, 5, E6502_OPF_UND },
128 { 0x48, "PHA", E6502_MODE_IMP, 1, 3, 0 },
129 { 0x49, "EOR", E6502_MODE_IMM, 2, 2, 0 },
130 { 0x4a, "LSR", E6502_MODE_A, 1, 2, 0 },
131 { 0x4b, "DB", E6502_MODE_DB, 1, 1, 0 },
132 { 0x4c, "JMP", E6502_MODE_JMP, 3, 3, E6502_OPF_BRA },
133 { 0x4d, "EOR", E6502_MODE_ABS, 3, 4, 0 },
134 { 0x4e, "LSR", E6502_MODE_ABS, 3, 6, 0 },
135 { 0x4f, "SRE", E6502_MODE_ABS, 3, 6, E6502_OPF_UND },
136 { 0x50, "BVC", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
137 { 0x51, "EOR", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
138 { 0x52, "DB", E6502_MODE_DB, 1, 1, 0 },
139 { 0x53, "SRE", E6502_MODE_IND_IDX_Y, 2, 8, E6502_OPF_UND },
140 { 0x54, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND },
141 { 0x55, "EOR", E6502_MODE_ZPG_X, 2, 4, 0 },
142 { 0x56, "LSR", E6502_MODE_ZPG_X, 2, 6, 0 },
143 { 0x57, "SRE", E6502_MODE_ZPG_X, 2, 6, E6502_OPF_UND },
144 { 0x58, "CLI", E6502_MODE_IMP, 1, 2, 0 },
145 { 0x59, "EOR", E6502_MODE_ABS_Y, 3, 4, 0 },
146 { 0x5a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND },
147 { 0x5b, "SRE", E6502_MODE_ABS_Y, 3, 7, E6502_OPF_UND },
148 { 0x5c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND },
149 { 0x5d, "EOR", E6502_MODE_IDX_IND_X, 3, 4, 0 },
150 { 0x5e, "LSR", E6502_MODE_ABS_X, 3, 7, 0 },
151 { 0x5f, "SRE", E6502_MODE_ABS_X, 3, 7, E6502_OPF_UND },
152 { 0x60, "RTS", E6502_MODE_IMP, 1, 6, E6502_OPF_RTS },
153 { 0x61, "ADC", E6502_MODE_IDX_IND_X, 2, 6, 0 },
154 { 0x62, "DB", E6502_MODE_DB, 1, 1, 0 },
155 { 0x63, "DB", E6502_MODE_DB, 1, 1, 0 },
156 { 0x64, "NOP", E6502_MODE_ZPG, 2, 3, E6502_OPF_UND },
157 { 0x65, "ADC", E6502_MODE_ZPG, 2, 3, 0 },
158 { 0x66, "ROR", E6502_MODE_ZPG, 2, 5, 0 },
159 { 0x67, "DB", E6502_MODE_DB, 1, 1, 0 },
160 { 0x68, "PLA", E6502_MODE_IMP, 1, 4, 0 },
161 { 0x69, "ADC", E6502_MODE_IMM, 2, 2, 0 },
162 { 0x6a, "ROR", E6502_MODE_A, 1, 2, 0 },
163 { 0x6b, "DB", E6502_MODE_DB, 1, 1, 0 },
164 { 0x6c, "JMP", E6502_MODE_ABS, 3, 5, E6502_OPF_BRA },
165 { 0x6d, "ADC", E6502_MODE_ABS, 3, 4, 0 },
166 { 0x6e, "ROR", E6502_MODE_ABS, 3, 6, 0 },
167 { 0x6f, "DB", E6502_MODE_DB, 1, 1, 0 },
168 { 0x70, "BVS", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
169 { 0x71, "ADC", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
170 { 0x72, "DB", E6502_MODE_DB, 1, 1, 0 },
171 { 0x73, "DB", E6502_MODE_DB, 1, 1, 0 },
172 { 0x74, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND },
173 { 0x75, "ADC", E6502_MODE_ZPG_X, 2, 4, 0 },
174 { 0x76, "ROR", E6502_MODE_ZPG_X, 2, 6, 0 },
175 { 0x77, "DB", E6502_MODE_DB, 1, 1, 0 },
176 { 0x78, "SEI", E6502_MODE_IMP, 1, 2, 0 },
177 { 0x79, "ADC", E6502_MODE_ABS_Y, 3, 4, 0 },
178 { 0x7a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND },
179 { 0x7b, "DB", E6502_MODE_DB, 1, 1, 0 },
180 { 0x7c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND },
181 { 0x7d, "ADC", E6502_MODE_ABS_X, 3, 4, 0 },
182 { 0x7e, "ROR", E6502_MODE_ABS_X, 3, 7, 0 },
183 { 0x7f, "DB", E6502_MODE_DB, 1, 1, 0 },
184 { 0x80, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND },
185 { 0x81, "STA", E6502_MODE_IDX_IND_X, 2, 6, 0 },
186 { 0x82, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND },
187 { 0x83, "DB", E6502_MODE_DB, 1, 1, 0 },
188 { 0x84, "STY", E6502_MODE_ZPG, 2, 3, 0 },
189 { 0x85, "STA", E6502_MODE_ZPG, 2, 3, 0 },
190 { 0x86, "STX", E6502_MODE_ZPG, 2, 3, 0 },
191 { 0x87, "DB", E6502_MODE_DB, 1, 1, 0 },
192 { 0x88, "DEY", E6502_MODE_IMP, 1, 2, 0 },
193 { 0x89, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND },
194 { 0x8a, "TXA", E6502_MODE_IMP, 1, 2, 0 },
195 { 0x8b, "DB", E6502_MODE_DB, 1, 1, 0 },
196 { 0x8c, "STY", E6502_MODE_ABS, 3, 4, 0 },
197 { 0x8d, "STA", E6502_MODE_ABS, 3, 4, 0 },
198 { 0x8e, "STX", E6502_MODE_ABS, 3, 4, 0 },
199 { 0x8f, "DB", E6502_MODE_DB, 1, 1, 0 },
200 { 0x90, "BCC", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
201 { 0x91, "STA", E6502_MODE_IND_IDX_Y, 2, 6, 0 },
202 { 0x92, "DB", E6502_MODE_DB, 1, 1, 0 },
203 { 0x93, "DB", E6502_MODE_DB, 1, 1, 0 },
204 { 0x94, "STY", E6502_MODE_ZPG_X, 2, 4, 0 },
205 { 0x95, "STA", E6502_MODE_ZPG_X, 2, 4, 0 },
206 { 0x96, "STX", E6502_MODE_ZPG_Y, 2, 4, 0 },
207 { 0x97, "DB", E6502_MODE_DB, 1, 1, 0 },
208 { 0x98, "TYA", E6502_MODE_IMP, 1, 2, 0 },
209 { 0x99, "STA", E6502_MODE_ABS_Y, 3, 5, 0 },
210 { 0x9a, "TXS", E6502_MODE_IMP, 1, 2, 0 },
211 { 0x9b, "DB", E6502_MODE_DB, 1, 1, 0 },
212 { 0x9c, "DB", E6502_MODE_DB, 1, 1, 0 },
213 { 0x9d, "STA", E6502_MODE_ABS_X, 3, 5, 0 },
214 { 0x9e, "DB", E6502_MODE_DB, 1, 1, 0 },
215 { 0x9f, "DB", E6502_MODE_DB, 1, 1, 0 },
216 { 0xa0, "LDY", E6502_MODE_IMM, 2, 2, 0 },
217 { 0xa1, "LDA", E6502_MODE_IDX_IND_X, 2, 6, 0 },
218 { 0xa2, "LDX", E6502_MODE_IMM, 2, 2, 0 },
219 { 0xa3, "DB", E6502_MODE_DB, 1, 1, 0 },
220 { 0xa4, "LDY", E6502_MODE_ZPG, 2, 3, 0 },
221 { 0xa5, "LDA", E6502_MODE_ZPG, 2, 3, 0 },
222 { 0xa6, "LDX", E6502_MODE_ZPG, 2, 3, 0 },
223 { 0xa7, "DB", E6502_MODE_DB, 1, 1, 0 },
224 { 0xa8, "TAY", E6502_MODE_IMP, 1, 2, 0 },
225 { 0xa9, "LDA", E6502_MODE_IMM, 2, 2, 0 },
226 { 0xaa, "TAX", E6502_MODE_IMP, 1, 2, 0 },
227 { 0xab, "DB", E6502_MODE_DB, 1, 1, 0 },
228 { 0xac, "LDY", E6502_MODE_ABS, 3, 4, 0 },
229 { 0xad, "LDA", E6502_MODE_ABS, 3, 4, 0 },
230 { 0xae, "LDX", E6502_MODE_ABS, 3, 4, 0 },
231 { 0xaf, "DB", E6502_MODE_DB, 1, 1, 0 },
232 { 0xb0, "BCS", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
233 { 0xb1, "LDA", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
234 { 0xb2, "DB", E6502_MODE_DB, 1, 1, 0 },
235 { 0xb3, "DB", E6502_MODE_DB, 1, 1, 0 },
236 { 0xb4, "LDY", E6502_MODE_ZPG_X, 2, 4, 0 },
237 { 0xb5, "LDA", E6502_MODE_ZPG_X, 2, 4, 0 },
238 { 0xb6, "LDX", E6502_MODE_ZPG_Y, 2, 4, 0 },
239 { 0xb7, "DB", E6502_MODE_DB, 1, 1, 0 },
240 { 0xb8, "CLV", E6502_MODE_IMP, 1, 2, 0 },
241 { 0xb9, "LDA", E6502_MODE_ABS_Y, 3, 4, 0 },
242 { 0xba, "TSX", E6502_MODE_IMP, 1, 2, 0 },
243 { 0xbb, "DB", E6502_MODE_DB, 1, 1, 0 },
244 { 0xbc, "LDY", E6502_MODE_ABS_X, 3, 4, 0 },
245 { 0xbd, "LDA", E6502_MODE_ABS_X, 3, 4, 0 },
246 { 0xbe, "LDX", E6502_MODE_ABS_Y, 3, 4, 0 },
247 { 0xbf, "DB", E6502_MODE_DB, 1, 1, 0 },
248 { 0xc0, "CPY", E6502_MODE_IMM, 2, 2, 0 },
249 { 0xc1, "CMP", E6502_MODE_IDX_IND_X, 2, 6, 0 },
250 { 0xc2, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND },
251 { 0xc3, "DB", E6502_MODE_DB, 1, 1, 0 },
252 { 0xc4, "CPY", E6502_MODE_ZPG, 2, 3, 0 },
253 { 0xc5, "CMP", E6502_MODE_ZPG, 2, 3, 0 },
254 { 0xc6, "DEC", E6502_MODE_ZPG, 2, 5, 0 },
255 { 0xc7, "DB", E6502_MODE_DB, 1, 1, 0 },
256 { 0xc8, "INY", E6502_MODE_IMP, 1, 2, 0 },
257 { 0xc9, "CMP", E6502_MODE_IMM, 2, 2, 0 },
258 { 0xca, "DEX", E6502_MODE_IMP, 1, 2, 0 },
259 { 0xcb, "DB", E6502_MODE_DB, 1, 1, 0 },
260 { 0xcc, "CPY", E6502_MODE_ABS, 3, 4, 0 },
261 { 0xcd, "CMP", E6502_MODE_ABS, 3, 4, 0 },
262 { 0xce, "DEC", E6502_MODE_ABS, 3, 6, 0 },
263 { 0xcf, "DB", E6502_MODE_DB, 1, 1, 0 },
264 { 0xd0, "BNE", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
265 { 0xd1, "CMP", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
266 { 0xd2, "DB", E6502_MODE_DB, 1, 1, 0 },
267 { 0xd3, "DB", E6502_MODE_DB, 1, 1, 0 },
268 { 0xd4, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND },
269 { 0xd5, "CMP", E6502_MODE_ZPG_X, 2, 4, 0 },
270 { 0xd6, "DEC", E6502_MODE_ZPG_X, 2, 6, 0 },
271 { 0xd7, "DB", E6502_MODE_DB, 1, 1, 0 },
272 { 0xd8, "CLD", E6502_MODE_IMP, 1, 2, 0 },
273 { 0xd9, "CMP", E6502_MODE_ABS_Y, 3, 4, 0 },
274 { 0xda, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND },
275 { 0xdb, "DB", E6502_MODE_DB, 1, 1, 0 },
276 { 0xdc, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND },
277 { 0xdd, "CMP", E6502_MODE_ABS_X, 3, 4, 0 },
278 { 0xde, "DEC", E6502_MODE_ABS_X, 3, 7, 0 },
279 { 0xdf, "DB", E6502_MODE_DB, 1, 1, 0 },
280 { 0xe0, "CPX", E6502_MODE_IMM, 2, 2, 0 },
281 { 0xe1, "SBC", E6502_MODE_IDX_IND_X, 2, 6, 0 },
282 { 0xe2, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND },
283 { 0xe3, "DB", E6502_MODE_DB, 1, 1, 0 },
284 { 0xe4, "CPX", E6502_MODE_ZPG, 2, 3, 0 },
285 { 0xe5, "SBC", E6502_MODE_ZPG, 2, 3, 0 },
286 { 0xe6, "INC", E6502_MODE_ZPG, 2, 5, 0 },
287 { 0xe7, "DB", E6502_MODE_DB, 1, 1, 0 },
288 { 0xe8, "INX", E6502_MODE_IMP, 1, 2, 0 },
289 { 0xe9, "SBC", E6502_MODE_IMM, 2, 2, 0 },
290 { 0xea, "NOP", E6502_MODE_IMP, 1, 2, 0 },
291 { 0xeb, "DB", E6502_MODE_DB, 1, 1, 0 },
292 { 0xec, "CPX", E6502_MODE_ABS, 3, 4, 0 },
293 { 0xed, "SBC", E6502_MODE_ABS, 3, 4, 0 },
294 { 0xee, "INC", E6502_MODE_ABS, 3, 6, 0 },
295 { 0xef, "DB", E6502_MODE_DB, 1, 1, 0 },
296 { 0xf0, "BEQ", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA },
297 { 0xf1, "SBC", E6502_MODE_IND_IDX_Y, 2, 5, 0 },
298 { 0xf2, "DB", E6502_MODE_DB, 1, 1, 0 },
299 { 0xf3, "DB", E6502_MODE_DB, 1, 1, 0 },
300 { 0xf4, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND },
301 { 0xf5, "SBC", E6502_MODE_ZPG_X, 2, 4, 0 },
302 { 0xf6, "INC", E6502_MODE_ZPG_X, 2, 6, 0 },
303 { 0xf7, "DB", E6502_MODE_DB, 1, 1, 0 },
304 { 0xf8, "SED", E6502_MODE_IMP, 1, 2, 0 },
305 { 0xf9, "SBC", E6502_MODE_ABS_Y, 3, 4, 0 },
306 { 0xfa, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND },
307 { 0xfb, "DB", E6502_MODE_DB, 1, 1, 0 },
308 { 0xfc, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND },
309 { 0xfd, "SBC", E6502_MODE_ABS_X, 3, 4, 0 },
310 { 0xfe, "INC", E6502_MODE_ABS_X, 3, 7, 0 },
311 { 0xff, "DB", E6502_MODE_DB, 1, 1, 0 }
312};
313
314
315void e6502_disasm (e6502_disasm_t *op, unsigned char *src, unsigned short pc)
316{
317 unsigned i;
318 unsigned opc;
319 e6502_dop_t *tab;
320
321 opc = src[0] & 0xff;
322 tab = &doptab[opc];
323
324 op->pc = pc;
325 op->flags = tab->flags;
326 op->dat_n = tab->size;
327 op->arg_n = 1;
328
329 strcpy (op->op, tab->mnemonic);
330
331 for (i = 0; i < tab->size; i++) {
332 op->dat[i] = src[i];
333 }
334
335 switch (tab->mode) {
336 case E6502_MODE_IDX_IND_X:
337 sprintf (op->arg1, "[[%02x + X]]", (unsigned) src[1]);
338 break;
339
340 case E6502_MODE_ZPG:
341 sprintf (op->arg1, "[%02x]", (unsigned) src[1]);
342 break;
343
344 case E6502_MODE_IMM:
345 sprintf (op->arg1, "#%02X", src[1] & 0xff);
346 break;
347
348 case E6502_MODE_ABS:
349 sprintf (op->arg1, "[%04X]", (unsigned) e6502_mk_uint16 (src[1], src[2]));
350 break;
351
352 case E6502_MODE_IND_IDX_Y:
353 sprintf (op->arg1, "[[%02X] + Y]", (unsigned) src[1]);
354 break;
355
356 case E6502_MODE_ZPG_X:
357 sprintf (op->arg1, "[%02X + X]", (unsigned) src[1]);
358 break;
359
360 case E6502_MODE_ZPG_Y:
361 sprintf (op->arg1, "[%02X + Y]", (unsigned) src[1]);
362 break;
363
364 case E6502_MODE_ABS_Y:
365 sprintf (op->arg1, "[%04X + Y]", (unsigned) e6502_mk_uint16 (src[1], src[2]));
366 break;
367
368 case E6502_MODE_ABS_X:
369 sprintf (op->arg1, "[%04X + X]", (unsigned) e6502_mk_uint16 (src[1], src[2]));
370 break;
371
372 case E6502_MODE_IMP:
373 op->arg_n = 0;
374 break;
375
376 case E6502_MODE_DB:
377 sprintf (op->arg1, "#%02X", src[0] & 0xff);
378 break;
379
380 case E6502_MODE_BRA:
381 sprintf (op->arg1, "%04X",
382 (unsigned) ((op->pc + 2 + e6502_mk_sint16 (src[1])) & 0xffff)
383 );
384 break;
385
386 case E6502_MODE_JMP:
387 sprintf (op->arg1, "%04X", (unsigned) e6502_mk_uint16 (src[1], src[2]));
388 break;
389
390 case E6502_MODE_A:
391 strcpy (op->arg1, "A");
392 break;
393
394 default:
395 strcpy (op->arg1, "???");
396 break;
397 }
398}
399
400void e6502_disasm_mem (e6502_t *c, e6502_disasm_t *op, unsigned short pc)
401{
402 unsigned i;
403 unsigned char src[4];
404
405 for (i = 0; i < 4; i++) {
406 src[i] = e6502_get_mem8 (c, (pc + i) & 0xffff);
407 }
408
409 e6502_disasm (op, src, pc);
410}
411
412void e6502_disasm_cur (e6502_t *c, e6502_disasm_t *op)
413{
414 e6502_disasm_mem (c, op, e6502_get_pc (c));
415}