1 // license:BSD-3-Clause
2 // copyright-holders:Wilbert Pol
3 /*******************************************************************
4
5 sm8500d.c
6 Sharp sm8500 CPU disassembly
7
8
9
10 *******************************************************************/
11
12 #include "emu.h"
13 #include "sm8500d.h"
14
15 const char *const sm8500_disassembler::s_mnemonic[] =
16 {
17 "adc", "adcw", "add", "addw", "and", "andw", "band", "bbc", "bbs",
18 "bclr", "bcmp", "bmov", "bor", "br", "btst", "bset", "bxor", "call", "cals", "clr",
19 "clrc", "cmp", "cmpw", "com", "comc", "da", "dbnz", "dec",
20 "decw", "di", "div", "ei", "exts", "halt", "inc", "incw",
21 "iret", "jmp", "mov", "movm", "movw", "mult", "neg", "nop", "or",
22 "orw", "pop", "popw", "push", "pushw", "ret", "rl", "rlc",
23 "rr", "rrc", "sbc", "sbcw", "setc", "sll", "sra", "srl", "stop",
24 "sub", "subw", "swap", "xor", "xorw", "mov PS0,", "invalid", "dm?",
25 /* unknowns */
26 "unk5A", "unk5B",
27
28 /* more complicated instructions */
29 "comp1A", "comp1B", "comp4F",
30 };
31
32 const uint32_t sm8500_disassembler::s_flags[] = {
33 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, 0,
35 0, 0, 0, 0, 0, 0, STEP_OVER, 0,
36 0, 0, 0, 0, 0, STEP_OVER, 0, 0,
37 STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0,
38 0, 0, 0, 0, 0, STEP_OUT, 0, 0,
39 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0, 0, 0, 0, 0,
41 0, 0,
42 0, 0, 0
43 };
44
45 const char *const sm8500_disassembler::sm8500_cond[16] = {
46 "F", "LT", "LE", "ULE", "OV", "MI", "Z", "C",
47 "T", "GE", "GT", "UGT", "NOV", "PL", "NZ", "NC"
48 };
49
50 const uint8_t sm8500_disassembler::sm8500_b2w[8] = {
51 0, 8, 2, 10, 4, 12, 6, 14
52 };
53
54 const sm8500_disassembler::sm8500dasm sm8500_disassembler::mnemonic[256] = {
55 /* 00 - 0F */
56 {zCLR, AM_R}, {zNEG,AM_R}, {zCOM,AM_R}, {zRR,AM_R},
57 {zRL, AM_R}, {zRRC,AM_R}, {zRLC,AM_R}, {zSRL,AM_R},
58 {zINC, AM_R}, {zDEC,AM_R}, {zSRA,AM_R}, {zSLL,AM_R},
59 {zDA, AM_R}, {zSWAP,AM_R}, {zPUSH,AM_R}, {zPOP,AM_R},
60 /* 10 - 1F */
61 {zCMP,AM_rr}, {zADD,AM_rr}, {zSUB,AM_rr}, {zADC,AM_rr},
62 {zSBC,AM_rr}, {zAND,AM_rr}, {zOR,AM_rr}, {zXOR,AM_rr},
63 {zINCW,AM_S}, {zDECW,AM_S}, {z1A,AM_1A}, {z1B,AM_1B},
64 {zBCLR,AM_riB}, {zBSET,AM_riB}, {zPUSHW,AM_S}, {zPOPW,AM_S},
65 /* 20 - 2F */
66 {zCMP,AM_rmb}, {zADD,AM_rmb}, {zSUB,AM_rmb}, {zADC,AM_rmb},
67 {zSBC,AM_rmb}, {zAND,AM_rmb}, {zOR,AM_rmb}, {zXOR,AM_rmb},
68 {zMOV,AM_rmb}, {zMOV,AM_mbr}, {zBBC,AM_bid}, {zBBS,AM_bid},
69 {zEXTS,AM_R}, {zDM,AM_i}, {zMOVPS0,AM_i}, {zBTST,AM_Ri},
70 /* 30 - 3F */
71 {zCMP,AM_rmw}, {zADD,AM_rmw}, {zSUB,AM_rmw}, {zADC,AM_rmw},
72 {zSBC,AM_rmw}, {zAND,AM_rmw}, {zOR,AM_rmw}, {zXOR,AM_rmw},
73 {zMOV,AM_rmw}, {zMOV,AM_mwr}, {zMOVW,AM_smw}, {zMOVW,AM_mws},
74 {zMOVW,AM_ss}, {zDM,AM_R}, {zJMP,AM_2}, {zCALL,AM_2},
75 /* 40 - 4F */
76 {zCMP,AM_RR}, {zADD,AM_RR}, {zSUB,AM_RR}, {zADC,AM_RR},
77 {zSBC,AM_RR}, {zAND,AM_RR}, {zOR,AM_RR}, {zXOR,AM_RR},
78 {zMOV,AM_RR}, {zCALL,AM_ii}, {zMOVW,AM_SS}, {zMOVW,AM_Sw},
79 {zMULT,AM_RR}, {zMULT,AM_iR}, {zBMOV,AM_bR}, {z4F,AM_4F},
80 /* 50 - 5F */
81 {zCMP,AM_iR}, {zADD,AM_iR}, {zSUB,AM_iR}, {zADC,AM_iR},
82 {zSBC,AM_iR}, {zAND,AM_iR}, {zOR,AM_iR}, {zXOR,AM_iR},
83 {zMOV, AM_iR}, {zINVLD,0}, {z5A,AM_5A}, {z5B,AM_5B},
84 {zDIV,AM_SS}, {zDIV,AM_iS}, {zMOVM,AM_RiR}, {zMOVM,AM_Rii},
85 /* 60 - 6F */
86 {zCMPW,AM_SS}, {zADDW,AM_SS}, {zSUBW,AM_SS}, {zADCW,AM_SS},
87 {zSBCW,AM_SS}, {zANDW,AM_SS}, {zORW,AM_SS}, {zXORW,AM_SS},
88 {zCMPW,AM_Sw}, {zADDW,AM_Sw}, {zSUBW,AM_Sw}, {zADCW,AM_Sw},
89 {zSBCW,AM_Sw}, {zANDW,AM_Sw}, {zORW,AM_Sw}, {zXORW,AM_Sw},
90 /* 70 - 7F */
91 {zDBNZ,AM_rbr}, {zDBNZ,AM_rbr}, {zDBNZ,AM_rbr}, {zDBNZ,AM_rbr},
92 {zDBNZ,AM_rbr}, {zDBNZ,AM_rbr}, {zDBNZ,AM_rbr}, {zDBNZ,AM_rbr},
93 {zMOVW,AM_riw}, {zMOVW,AM_riw}, {zMOVW,AM_riw}, {zMOVW,AM_riw},
94 {zMOVW,AM_riw}, {zMOVW,AM_riw}, {zMOVW,AM_riw}, {zMOVW,AM_riw},
95 /* 80 - 8F */
96 {zBBC,AM_Rbr}, {zBBC,AM_Rbr}, {zBBC,AM_Rbr}, {zBBC,AM_Rbr},
97 {zBBC,AM_Rbr}, {zBBC,AM_Rbr}, {zBBC,AM_Rbr}, {zBBC,AM_Rbr},
98 {zBBS,AM_Rbr}, {zBBS,AM_Rbr}, {zBBS,AM_Rbr}, {zBBS,AM_Rbr},
99 {zBBS,AM_Rbr}, {zBBS,AM_Rbr}, {zBBS,AM_Rbr}, {zBBS,AM_Rbr},
100 /* 90 - 9F */
101 {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp},
102 {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp},
103 {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp},
104 {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp}, {zJMP,AM_cjp},
105 /* A0 - AF */
106 {zBCLR,AM_Rb}, {zBCLR,AM_Rb}, {zBCLR,AM_Rb}, {zBCLR,AM_Rb},
107 {zBCLR,AM_Rb}, {zBCLR,AM_Rb}, {zBCLR,AM_Rb}, {zBCLR,AM_Rb},
108 {zBSET,AM_Rb}, {zBSET,AM_Rb}, {zBSET,AM_Rb}, {zBSET,AM_Rb},
109 {zBSET,AM_Rb}, {zBSET,AM_Rb}, {zBSET,AM_Rb}, {zBSET,AM_Rb},
110 /* B0 - BF */
111 {zMOV,AM_rR}, {zMOV,AM_rR}, {zMOV,AM_rR}, {zMOV,AM_rR},
112 {zMOV,AM_rR}, {zMOV,AM_rR}, {zMOV,AM_rR}, {zMOV,AM_rR},
113 {zMOV,AM_Rr}, {zMOV,AM_Rr}, {zMOV,AM_Rr}, {zMOV,AM_Rr},
114 {zMOV,AM_Rr}, {zMOV,AM_Rr}, {zMOV,AM_Rr}, {zMOV,AM_Rr},
115 /* C0 - CF */
116 {zMOV,AM_rib}, {zMOV,AM_rib}, {zMOV,AM_rib}, {zMOV,AM_rib},
117 {zMOV,AM_rib}, {zMOV,AM_rib}, {zMOV,AM_rib}, {zMOV,AM_rib},
118 {zMOV,AM_pi}, {zMOV,AM_pi}, {zMOV,AM_pi}, {zMOV,AM_pi},
119 {zMOV,AM_pi}, {zMOV,AM_pi}, {zMOV,AM_pi}, {zMOV,AM_pi},
120 /* D0 - DF */
121 {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr},
122 {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr},
123 {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr},
124 {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr}, {zBR,AM_cbr},
125 /* E0 - EF */
126 {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS},
127 {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS},
128 {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS},
129 {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS}, {zCALS,AM_CALS},
130 /* F0 - FF */
131 {zSTOP,0}, {zHALT,0}, {zINVLD,0}, {zINVLD,0},
132 {zINVLD,0}, {zINVLD,0}, {zINVLD,0}, {zINVLD,0},
133 {zRET,0}, {zIRET,0}, {zCLRC,0}, {zCOMC,0},
134 {zSETC,0}, {zEI,0}, {zDI,0}, {zNOP,0},
135
136 };
137
opcode_alignment() const138 u32 sm8500_disassembler::opcode_alignment() const
139 {
140 return 1;
141 }
142
disassemble(std::ostream & stream,offs_t pc,const data_buffer & opcodes,const data_buffer & params)143 offs_t sm8500_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
144 {
145 const sm8500dasm *instr;
146 uint8_t op;
147 int8_t offset;
148 uint16_t ea;
149 uint16_t ea2;
150 uint16_t ea3;
151 offs_t pos = pc;
152
153 op = opcodes.r8(pos++);
154
155 instr = &mnemonic[op];
156
157 if ( instr->arguments )
158 {
159 if ( instr->arguments != AM_1A && instr->arguments != AM_1B && instr->arguments != AM_4F ) {
160 util::stream_format(stream, "%-4s ", s_mnemonic[ instr->mnemonic ]);
161 }
162 switch( instr->arguments ) {
163 case AM_R:
164 ea = opcodes.r8(pos++);
165 util::stream_format(stream, "R%02Xh", ea);
166 break;
167 case AM_iR:
168 util::stream_format(stream, "R%02Xh, $%02X", opcodes.r8(pos+1), opcodes.r8(pos));
169 pos += 2;
170 break;
171 case AM_iS:
172 util::stream_format(stream, "RR%02Xh, $%02X", opcodes.r8(pos+1), opcodes.r8(pos));
173 pos += 2;
174 break;
175 case AM_Sw:
176 ea2 = opcodes.r8(pos++);
177 ea = opcodes.r8(pos++) << 8;
178 ea += opcodes.r8(pos++);
179 util::stream_format(stream, "RR%02Xh, $%04X", ea2, ea);
180 break;
181 case AM_rib:
182 ea = opcodes.r8(pos++);
183 util::stream_format(stream, "r%02Xh, $%02X", op & 0x07, ea);
184 break;
185 case AM_riw:
186 ea = opcodes.r8(pos++) << 8;
187 ea += opcodes.r8(pos++);
188 util::stream_format(stream, "rr%02Xh, $%04X", sm8500_b2w[op & 0x07], ea);
189 break;
190 case AM_rmb:
191 ea = opcodes.r8(pos++);
192 util::stream_format(stream, "r%02Xh,", ( ea >> 3 ) & 0x07);
193 switch( ea & 0xC0 ) {
194 case 0x00:
195 util::stream_format(stream, "@r%02Xh", ea & 0x07); break;
196 case 0x40:
197 util::stream_format(stream, "(r%02Xh)+", ea & 0x07); break;
198 case 0x80:
199 ea2 = opcodes.r8(pos++);
200 if ( ea & 0x07 ) {
201 util::stream_format(stream, "$%02X(r%02Xh)", ea2, ea & 0x07);
202 } else {
203 util::stream_format(stream, "@$%02X", ea2);
204 }
205 break;
206 case 0xC0:
207 util::stream_format(stream, "-(r%02Xh)", ea & 0x07); break;
208 }
209 break;
210 case AM_mbr:
211 ea = opcodes.r8(pos++);
212 switch( ea & 0xC0 ) {
213 case 0x00:
214 util::stream_format(stream, "@r%02Xh", ea & 0x07); break;
215 case 0x40:
216 util::stream_format(stream, "(r%02Xh)+", ea & 0x07); break;
217 case 0x80:
218 ea2 = opcodes.r8(pos++);
219 if ( ea & 0x07 ) {
220 util::stream_format(stream, "$%02X(r%02Xh)", ea2, ea & 0x07);
221 } else {
222 util::stream_format(stream, "@$%02X", ea2);
223 }
224 break;
225 case 0xC0:
226 util::stream_format(stream, "-(r%02Xh)", ea & 0x07); break;
227 }
228 util::stream_format(stream, ",r%02Xh", ( ea >> 3 ) & 0x07);
229 break;
230 case AM_rmw:
231 ea = opcodes.r8(pos++);
232 util::stream_format(stream, "r%02Xh,", ( ea >> 3 ) & 0x07);
233 switch( ea & 0xC0 ) {
234 case 0x00:
235 util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break;
236 case 0x40:
237 util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break;
238 case 0x80:
239 ea2 = opcodes.r8(pos++) << 8;
240 ea2 += opcodes.r8(pos++);
241 if ( ea & 0x07 ) {
242 util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]);
243 } else {
244 util::stream_format(stream, "@$%04X", ea2);
245 }
246 break;
247 case 0xC0:
248 util::stream_format(stream, "-(rr%02Xh)", sm8500_b2w[ea & 0x07]); break;
249 }
250 break;
251 case AM_mwr:
252 ea = opcodes.r8(pos++);
253 switch( ea & 0xC0 ) {
254 case 0x00:
255 util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break;
256 case 0x40:
257 util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break;
258 case 0x80:
259 ea2 = opcodes.r8(pos++) << 8;
260 ea2 += opcodes.r8(pos++);
261 if ( ea & 0x07 ) {
262 util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]);
263 } else {
264 util::stream_format(stream, "@$%04X", ea2);
265 }
266 break;
267 case 0xC0:
268 util::stream_format(stream, "-(rr%02Xh)", sm8500_b2w[ea & 0x07]); break;
269 }
270 util::stream_format(stream, ",r%02Xh", ( ea >> 3 ) & 0x07);
271 break;
272 case AM_smw:
273 ea = opcodes.r8(pos++);
274 util::stream_format(stream, "rr%02Xh,", sm8500_b2w[( ea >> 3 ) & 0x07]);
275 switch( ea & 0xC0 ) {
276 case 0x00:
277 util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break;
278 case 0x40:
279 util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break;
280 case 0x80:
281 ea2 = opcodes.r8(pos++) << 8;
282 ea2 += opcodes.r8(pos++);
283 if ( ea & 0x07 ) {
284 util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]);
285 } else {
286 util::stream_format(stream, "@$%04X", ea2);
287 }
288 break;
289 case 0xC0:
290 util::stream_format(stream, "-(rr%02Xh)", sm8500_b2w[ea & 0x07]); break;
291 }
292 break;
293 case AM_mws:
294 ea = opcodes.r8(pos++);
295 switch( ea & 0xC0 ) {
296 case 0x00:
297 util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break;
298 case 0x40:
299 util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break;
300 case 0x80:
301 ea2 = opcodes.r8(pos++) << 8;
302 ea2 += opcodes.r8(pos++);
303 if ( ea & 0x07 ) {
304 util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]);
305 } else {
306 util::stream_format(stream, "@$%04X", ea2);
307 }
308 break;
309 case 0xC0:
310 util::stream_format(stream, "-(rr%02Xh)", sm8500_b2w[ea & 0x07]); break;
311 }
312 util::stream_format(stream, ",rr%02Xh", sm8500_b2w[( ea >> 3 ) & 0x07]);
313 break;
314 case AM_cbr:
315 offset = (int8_t) opcodes.r8(pos++);
316 util::stream_format(stream, "%s,$%04X", sm8500_cond[ op & 0x0F ], pos + offset);
317 break;
318 case AM_rbr:
319 offset = (int8_t) opcodes.r8(pos++);
320 util::stream_format(stream, "r%02Xh,$%04X", op & 0x07, pos + offset);
321 break;
322 case AM_cjp:
323 ea = opcodes.r8(pos++) << 8;
324 ea += opcodes.r8(pos++);
325 util::stream_format(stream, "%s,$%04X", sm8500_cond[ op & 0x0F], ea);
326 break;
327 case AM_rr:
328 ea = opcodes.r8(pos++);
329 switch( ea & 0xc0 ) {
330 case 0x00:
331 util::stream_format(stream, "r%02Xh,r%02Xh", (ea >> 3 ) & 0x07, ea & 0x07);
332 break;
333 case 0x40:
334 case 0x80:
335 case 0xC0:
336 util::stream_format(stream, "undef");
337 break;
338 }
339 break;
340 case AM_r1:
341 ea = opcodes.r8(pos++);
342 switch( ea & 0xC0 ) {
343 case 0x00:
344 util::stream_format(stream, "@r%02Xh", (ea >> 3 ) & 0x07);
345 break;
346 case 0x40:
347 case 0x80:
348 case 0xC0:
349 util::stream_format(stream, "undef");
350 break;
351 }
352 break;
353 case AM_S:
354 ea = opcodes.r8(pos++);
355 util::stream_format(stream, "RR%02Xh", ea);
356 break;
357 case AM_pi:
358 ea = opcodes.r8(pos++);
359 util::stream_format(stream, "r%02Xh, $%02X", 0x10 + (op & 0x07), ea);
360 break;
361 case AM_Ri:
362 ea = opcodes.r8(pos++);
363 ea2 = opcodes.r8(pos++);
364 util::stream_format(stream, "R%02Xh,$%02X", ea, ea2);
365 break;
366 case AM_i:
367 ea = opcodes.r8(pos++);
368 util::stream_format(stream, "$%02X", ea);
369 break;
370 case AM_ii:
371 ea = opcodes.r8(pos++) << 8;
372 ea += opcodes.r8(pos++);
373 util::stream_format(stream, "$%04X", ea);
374 break;
375 case AM_5A:
376 ea = opcodes.r8(pos++);
377 ea2 = opcodes.r8(pos++);
378 switch( ea & 0xC0 ) {
379 case 0x00:
380 util::stream_format(stream, "CMP (rr%02Xh),$%02Xh", ea & 7, ea2); break;
381 case 0x40:
382 util::stream_format(stream, "undef $%04X", ea); break;
383 case 0x80:
384 ea3 = opcodes.r8(pos++);
385 util::stream_format(stream, "CMP (rr%02Xh+%02Xh),$%02Xh", ea & 7, ea2, ea3); break;
386 case 0xC0:
387 util::stream_format(stream, "undef $%04X", ea); break;
388 }
389 break;
390 case AM_5B:
391 ea = opcodes.r8(pos++);
392 ea2 = opcodes.r8(pos++);
393 ea3 = (ea << 8) | ea2;
394 switch( ea & 0xC0 ) {
395 case 0x40:
396 util::stream_format(stream, "MOV (rr%02Xh)+,$%02Xh", ea & 7, ea2); break; // could be AND instead of MOV
397 default:
398 util::stream_format(stream, "undef $%04X", ea3); break;
399 }
400 break;
401 case AM_ss:
402 ea = opcodes.r8(pos++);
403 switch( ea & 0xC0 ) {
404 case 0x00:
405 util::stream_format(stream, "rr%02Xh,rr%02Xh", sm8500_b2w[( ea >> 3 ) & 0x07], sm8500_b2w[ea & 0x07]); break;
406 case 0x40:
407 util::stream_format(stream, "undef"); break;
408 case 0x80:
409 util::stream_format(stream, "undef"); break;
410 case 0xC0:
411 util::stream_format(stream, "undef"); break;
412 }
413 break;
414 case AM_RR:
415 ea = opcodes.r8(pos++);
416 ea2 = opcodes.r8(pos++);
417 util::stream_format(stream, "R%02Xh,R%02Xh", ea2, ea);
418 break;
419 case AM_2:
420 ea = opcodes.r8(pos++);
421 switch( ea & 0xC0 ) {
422 case 0x00:
423 util::stream_format(stream, "rr%02Xh", sm8500_b2w[ea & 0x07]); break;
424 case 0x40:
425 ea2 = opcodes.r8(pos++) << 8;
426 ea2 += opcodes.r8(pos++);
427 if ( ea & 0x38 ) {
428 util::stream_format(stream, "@$%04X(r%02Xh)", ea2, ( ea >> 3 ) & 0x07);
429 } else {
430 util::stream_format(stream, "@$%04X", ea2);
431 }
432 break;
433 case 0x80:
434 util::stream_format(stream, "undef"); break;
435 case 0xC0:
436 util::stream_format(stream, "undef"); break;
437 }
438 break;
439 case AM_SS:
440 ea = opcodes.r8(pos++);
441 ea2 = opcodes.r8(pos++);
442 util::stream_format(stream, "RR%02Xh,RR%02Xh", ea2, ea);
443 break;
444 case AM_bR:
445 ea = opcodes.r8(pos++);
446 ea2 = opcodes.r8(pos++);
447 switch( ea & 0xC0 ) {
448 case 0x00:
449 util::stream_format(stream, "BF,R%02Xh,#%d", ea2, ea & 0x07); break;
450 case 0x40:
451 util::stream_format(stream, "R%02Xh,#%d,BF", ea2, ea & 0x07); break;
452 case 0x80:
453 util::stream_format(stream, "undef"); break;
454 case 0xC0:
455 util::stream_format(stream, "undef"); break;
456 }
457 break;
458 case AM_Rbr:
459 ea = opcodes.r8(pos++);
460 offset = (int8_t) opcodes.r8(pos++);
461 util::stream_format(stream, "R%02Xh,#%d,$%04X", ea, op & 0x07, pos + offset);
462 break;
463 case AM_Rb:
464 ea = opcodes.r8(pos++);
465 util::stream_format(stream, "R%02Xh,#%d", ea, op&0x07);
466 break;
467 case AM_rR:
468 ea = opcodes.r8(pos++);
469 util::stream_format(stream, "r%02Xh,R%02Xh", op & 0x07, ea);
470 break;
471 case AM_Rr:
472 ea = opcodes.r8(pos++);
473 util::stream_format(stream, "R%02Xh,r%02Xh", ea, op & 0x07);
474 break;
475 case AM_Rii:
476 ea = opcodes.r8(pos++);
477 util::stream_format(stream, "R%02Xh,", ea);
478 ea = opcodes.r8(pos++);
479 util::stream_format(stream, "$%02X,", ea);
480 ea = opcodes.r8(pos++);
481 util::stream_format(stream, "$%02X", ea);
482 break;
483 case AM_RiR:
484 ea = opcodes.r8(pos++);
485 util::stream_format(stream, "R%02Xh,", ea);
486 ea = opcodes.r8(pos++);
487 util::stream_format(stream, "$%02X,", ea);
488 ea = opcodes.r8(pos++);
489 util::stream_format(stream, "R%02Xh", ea);
490 break;
491 case AM_riB:
492 ea = opcodes.r8(pos++);
493 ea2 = opcodes.r8(pos++);
494 switch( ea & 0xC0 ) {
495 case 0x00:
496 util::stream_format(stream, "#%2x(r%02Xh),#%d", ea2, ea >> 3, ea & 0x07);
497 break;
498 case 0x40:
499 util::stream_format(stream, "undef"); break;
500 case 0x80:
501 util::stream_format(stream, "undef"); break;
502 case 0xC0:
503 util::stream_format(stream, "undef"); break;
504 }
505 break;
506 case AM_CALS:
507 ea = opcodes.r8(pos++);
508 util::stream_format(stream, "$%04X", 0x1000 | ( ( op & 0x0f ) << 8 ) | ea);
509 break;
510 case AM_bid:
511 ea = opcodes.r8(pos++);
512 ea2 = opcodes.r8(pos++);
513 if ( ea & 0x38 ) {
514 util::stream_format(stream, "$%02X(r%02Xh)", ea2, ( ea >> 3 ) & 0x07);
515 } else {
516 util::stream_format(stream, "$%04X", 0xFF00 + ea2);
517 }
518 util::stream_format(stream, ",#%d,", ea & 0x07);
519 offset = (int8_t) opcodes.r8(pos++);
520 util::stream_format(stream, "$%04X", pos + offset);
521 break;
522 case AM_1A:
523 ea = opcodes.r8(pos++);
524 switch( ea & 0x07 ) {
525 case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zCLR ]); break;
526 case 0x01: util::stream_format(stream, "%-4s ", s_mnemonic[ zNEG ]); break;
527 case 0x02: util::stream_format(stream, "%-4s ", s_mnemonic[ zCOM ]); break;
528 case 0x03: util::stream_format(stream, "%-4s ", s_mnemonic[ zRR ]); break;
529 case 0x04: util::stream_format(stream, "%-4s ", s_mnemonic[ zRL ]); break;
530 case 0x05: util::stream_format(stream, "%-4s ", s_mnemonic[ zRRC ]); break;
531 case 0x06: util::stream_format(stream, "%-4s ", s_mnemonic[ zRLC ]); break;
532 case 0x07: util::stream_format(stream, "%-4s ", s_mnemonic[ zSRL ]); break;
533 }
534 util::stream_format(stream, "@r%02Xh", ( ea >> 3 ) & 0x07);
535 break;
536 case AM_1B:
537 ea = opcodes.r8(pos++);
538 switch( ea & 0x07 ) {
539 case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zINC ]); break;
540 case 0x01: util::stream_format(stream, "%-4s ", s_mnemonic[ zDEC ]); break;
541 case 0x02: util::stream_format(stream, "%-4s ", s_mnemonic[ zSRA ]); break;
542 case 0x03: util::stream_format(stream, "%-4s ", s_mnemonic[ zSLL ]); break;
543 case 0x04: util::stream_format(stream, "%-4s ", s_mnemonic[ zDA ]); break;
544 case 0x05: util::stream_format(stream, "%-4s ", s_mnemonic[ zSWAP ]); break;
545 case 0x06: util::stream_format(stream, "%-4s ", s_mnemonic[ zPUSH ]); break;
546 case 0x07: util::stream_format(stream, "%-4s ", s_mnemonic[ zPOP ]); break;
547 }
548 util::stream_format(stream, "@r%02Xh", ( ea >> 3 ) & 0x07);
549 break;
550 case AM_4F:
551 ea = opcodes.r8(pos++);
552 ea2 = opcodes.r8(pos++);
553 switch( ea & 0xc0 ) {
554 case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zBCMP ]); break;
555 case 0x40: util::stream_format(stream, "%-4s ", s_mnemonic[ zBAND ]); break;
556 case 0x80: util::stream_format(stream, "%-4s ", s_mnemonic[ zBOR ]); break;
557 case 0xC0: util::stream_format(stream, "%-4s ", s_mnemonic[ zBXOR ]); break;
558 }
559 if ( ! ( ea & 0x80 ) ) {
560 util::stream_format(stream, "BF,");
561 }
562 util::stream_format(stream, "R%02Xh,$%02X", ea2, ea & 0x07);
563 if ( ea & 0x80 ) {
564 util::stream_format(stream, ",BF");
565 }
566 break;
567 }
568 }
569 else
570 {
571 util::stream_format(stream, "%s", s_mnemonic[ instr->mnemonic ]);
572 }
573
574 return (pos - pc) | s_flags[instr->mnemonic] | SUPPORTED;
575 }
576