gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / opcodes / z80-dis.c
CommitLineData
6655dba2 1/* Print Z80, Z180, EZ80 and R800 instructions
b3adc24a 2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
3c9b82ba
NC
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
4
9b201bb5
NC
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
3c9b82ba 8 it under the terms of the GNU General Public License as published by
9b201bb5
NC
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
3c9b82ba 11
9b201bb5
NC
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
3c9b82ba
NC
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22#include "sysdep.h"
88c1242d 23#include "disassemble.h"
3c9b82ba
NC
24#include <stdio.h>
25
26struct buffer
27{
28 bfd_vma base;
29 int n_fetch;
30 int n_used;
6655dba2
SB
31 signed char data[6];
32 long inss; /* instruction set bit mask, taken from bfd_mach */
33 int nn_len; /* address length: 2 - Z80 mode, 3 - ADL mode*/
3c9b82ba
NC
34} ;
35
6655dba2 36typedef int (*func)(struct buffer *, disassemble_info *, const char *);
3c9b82ba
NC
37
38struct tab_elt
39{
40 unsigned char val;
41 unsigned char mask;
42 func fp;
6655dba2
SB
43 const char * text;
44 unsigned inss; /* bit mask of supported bfd_mach_* or 0 for all mach */
3c9b82ba
NC
45} ;
46
6655dba2
SB
47#define INSS_ALL 0
48#define INSS_Z80 ((1 << bfd_mach_z80) | (1 << bfd_mach_z80strict) | (1 << bfd_mach_z80full))
49#define INSS_R800 (1 << bfd_mach_r800)
50#define INSS_GBZ80 (1 << bfd_mach_gbz80)
51#define INSS_Z180 (1 << bfd_mach_z180)
52#define INSS_EZ80_Z80 (1 << bfd_mach_ez80_z80)
53#define INSS_EZ80_ADL (1 << bfd_mach_ez80_adl)
54#define INSS_EZ80 (INSS_EZ80_ADL | INSS_EZ80_Z80)
9fc0b501 55#define INSS_Z80N (1 << bfd_mach_z80n)
6655dba2 56
9e919b5f 57#define TXTSIZ 24
3c9b82ba 58/* Names of 16-bit registers. */
6655dba2 59static const char * rr_str[] = { "bc", "de", "hl", "sp" };
3c9b82ba 60/* Names of 8-bit registers. */
6655dba2 61static const char * r_str[] = { "b", "c", "d", "e", "h", "l", "(hl)", "a" };
3c9b82ba 62/* Texts for condition codes. */
6655dba2 63static const char * cc_str[] = { "nz", "z", "nc", "c", "po", "pe", "p", "m" };
3c9b82ba 64/* Instruction names for 8-bit arithmetic, operand "a" is often implicit */
6655dba2 65static const char * arit_str[] =
3c9b82ba
NC
66{
67 "add a,", "adc a,", "sub ", "sbc a,", "and ", "xor ", "or ", "cp "
68} ;
9fc0b501
SB
69static const char * arit_str_gbz80[] =
70{
71 "add a,", "adc a,", "sub a,", "sbc a,", "and ", "xor ", "or ", "cp "
72} ;
6655dba2
SB
73static const char * arit_str_ez80[] =
74{
75 "add a,", "adc a,", "sub a,", "sbc a,", "and a,", "xor a,", "or a,", "cp a,"
76} ;
77
3c9b82ba 78\f
6655dba2 79static int
9fc0b501 80mach_inst (struct buffer *buf, const struct tab_elt *p)
6655dba2
SB
81{
82 return !p->inss || (p->inss & buf->inss);
83}
84
3c9b82ba
NC
85static int
86fetch_data (struct buffer *buf, disassemble_info * info, int n)
87{
88 int r;
89
40c75bc8 90 if (buf->n_fetch + n > (int)sizeof (buf->data))
3c9b82ba
NC
91 abort ();
92
93 r = info->read_memory_func (buf->base + buf->n_fetch,
9e919b5f 94 (unsigned char*) buf->data + buf->n_fetch,
3c9b82ba
NC
95 n, info);
96 if (r == 0)
97 buf->n_fetch += n;
98 return !r;
99}
100
101static int
6655dba2 102prt (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
103{
104 info->fprintf_func (info->stream, "%s", txt);
105 buf->n_used = buf->n_fetch;
106 return 1;
107}
108
109static int
6655dba2 110prt_e (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
111{
112 char e;
113 int target_addr;
114
115 if (fetch_data (buf, info, 1))
116 {
117 e = buf->data[1];
118 target_addr = (buf->base + 2 + e) & 0xffff;
119 buf->n_used = buf->n_fetch;
120 info->fprintf_func (info->stream, "%s0x%04x", txt, target_addr);
121 }
122 else
123 buf->n_used = -1;
124
125 return buf->n_used;
126}
127
128static int
6655dba2 129jr_cc (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
130{
131 char mytxt[TXTSIZ];
132
133 snprintf (mytxt, TXTSIZ, txt, cc_str[(buf->data[0] >> 3) & 3]);
134 return prt_e (buf, info, mytxt);
135}
136
137static int
6655dba2 138prt_nn (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
139{
140 int nn;
141 unsigned char *p;
6655dba2 142 int i;
3c9b82ba
NC
143
144 p = (unsigned char*) buf->data + buf->n_fetch;
6655dba2 145 if (fetch_data (buf, info, buf->nn_len))
3c9b82ba 146 {
6655dba2
SB
147 nn = 0;
148 i = buf->nn_len;
149 while (i--)
150 nn = nn * 0x100 + p[i];
3c9b82ba
NC
151 info->fprintf_func (info->stream, txt, nn);
152 buf->n_used = buf->n_fetch;
153 }
154 else
155 buf->n_used = -1;
156 return buf->n_used;
157}
158
159static int
6655dba2 160prt_rr_nn (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
161{
162 char mytxt[TXTSIZ];
d0411736 163 int rr;
3c9b82ba 164
43e65147 165 rr = (buf->data[buf->n_fetch - 1] >> 4) & 3;
d0411736 166 snprintf (mytxt, TXTSIZ, txt, rr_str[rr]);
3c9b82ba
NC
167 return prt_nn (buf, info, mytxt);
168}
169
170static int
6655dba2 171prt_rr (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
172{
173 info->fprintf_func (info->stream, "%s%s", txt,
174 rr_str[(buf->data[buf->n_fetch - 1] >> 4) & 3]);
175 buf->n_used = buf->n_fetch;
176 return buf->n_used;
177}
178
179static int
6655dba2 180prt_n (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
181{
182 int n;
183 unsigned char *p;
184
185 p = (unsigned char*) buf->data + buf->n_fetch;
186
187 if (fetch_data (buf, info, 1))
188 {
189 n = p[0];
190 info->fprintf_func (info->stream, txt, n);
191 buf->n_used = buf->n_fetch;
192 }
193 else
194 buf->n_used = -1;
195
196 return buf->n_used;
197}
198
9fc0b501
SB
199static int
200prt_n_n (struct buffer *buf, disassemble_info * info, const char *txt)
201{
202 char mytxt[TXTSIZ];
203 int n;
204 unsigned char *p;
205
206 p = (unsigned char*) buf->data + buf->n_fetch;
207
208 if (fetch_data (buf, info, 1))
209 {
210 n = p[0];
211 snprintf (mytxt, TXTSIZ, txt, n);
212 buf->n_used = buf->n_fetch;
213 }
214 else
215 buf->n_used = -1;
216
217 return prt_n (buf, info, mytxt);
218}
219
3c9b82ba 220static int
6655dba2
SB
221prt_r_n (struct buffer *buf, disassemble_info * info, const char *txt)
222{
223 char mytxt[TXTSIZ];
224 int r;
225
226 r = (buf->data[buf->n_fetch - 1] >> 3) & 7;
227 snprintf (mytxt, TXTSIZ, txt, r_str[r]);
228 return prt_n (buf, info, mytxt);
229}
230
231static int
232ld_r_n (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
233{
234 char mytxt[TXTSIZ];
235
6655dba2 236 snprintf (mytxt, TXTSIZ, txt, r_str[(buf->data[buf->n_fetch - 1] >> 3) & 7]);
3c9b82ba
NC
237 return prt_n (buf, info, mytxt);
238}
239
240static int
6655dba2 241prt_r (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
242{
243 info->fprintf_func (info->stream, txt,
244 r_str[(buf->data[buf->n_fetch - 1] >> 3) & 7]);
245 buf->n_used = buf->n_fetch;
246 return buf->n_used;
247}
248
249static int
6655dba2 250ld_r_r (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
251{
252 info->fprintf_func (info->stream, txt,
253 r_str[(buf->data[buf->n_fetch - 1] >> 3) & 7],
254 r_str[buf->data[buf->n_fetch - 1] & 7]);
255 buf->n_used = buf->n_fetch;
256 return buf->n_used;
257}
258
259static int
6655dba2 260prt_d (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba 261{
6655dba2
SB
262 int d;
263 signed char *p;
264
265 p = buf->data + buf->n_fetch;
266
267 if (fetch_data (buf, info, 1))
268 {
269 d = p[0];
270 info->fprintf_func (info->stream, txt, d);
271 buf->n_used = buf->n_fetch;
272 }
273 else
274 buf->n_used = -1;
275
276 return buf->n_used;
277}
278
279static int
280prt_rr_d (struct buffer *buf, disassemble_info * info, const char *txt)
281{
282 char mytxt[TXTSIZ];
283 int rr;
284
285 rr = (buf->data[buf->n_fetch - 1] >> 4) & 3;
286 if (rr == 3) /* SP is not supported */
287 return 0;
288
289 snprintf (mytxt, TXTSIZ, txt, rr_str[rr]);
290 return prt_d (buf, info, mytxt);
291}
292
293static int
294arit_r (struct buffer *buf, disassemble_info * info, const char *txt)
295{
296 const char * const *arit;
9fc0b501
SB
297
298 if (buf->inss & INSS_EZ80)
299 arit = arit_str_ez80;
300 else if (buf->inss & INSS_GBZ80)
301 arit = arit_str_gbz80;
302 else
303 arit = arit_str;
304
3c9b82ba 305 info->fprintf_func (info->stream, txt,
6655dba2
SB
306 arit[(buf->data[buf->n_fetch - 1] >> 3) & 7],
307 r_str[buf->data[buf->n_fetch - 1] & 7]);
3c9b82ba
NC
308 buf->n_used = buf->n_fetch;
309 return buf->n_used;
310}
311
312static int
6655dba2 313prt_cc (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
314{
315 info->fprintf_func (info->stream, "%s%s", txt,
316 cc_str[(buf->data[0] >> 3) & 7]);
317 buf->n_used = buf->n_fetch;
318 return buf->n_used;
319}
320
321static int
6655dba2 322pop_rr (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
323{
324 static char *rr_stack[] = { "bc","de","hl","af"};
325
326 info->fprintf_func (info->stream, "%s %s", txt,
327 rr_stack[(buf->data[0] >> 4) & 3]);
328 buf->n_used = buf->n_fetch;
329 return buf->n_used;
330}
331
332
333static int
6655dba2 334jp_cc_nn (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
335{
336 char mytxt[TXTSIZ];
337
338 snprintf (mytxt,TXTSIZ,
339 "%s%s,0x%%04x", txt, cc_str[(buf->data[0] >> 3) & 7]);
340 return prt_nn (buf, info, mytxt);
341}
342
343static int
6655dba2 344arit_n (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
345{
346 char mytxt[TXTSIZ];
6655dba2 347 const char * const *arit;
3c9b82ba 348
9fc0b501
SB
349 if (buf->inss & INSS_EZ80)
350 arit = arit_str_ez80;
351 else if (buf->inss & INSS_GBZ80)
352 arit = arit_str_gbz80;
353 else
354 arit = arit_str;
355
6655dba2 356 snprintf (mytxt,TXTSIZ, txt, arit[(buf->data[0] >> 3) & 7]);
3c9b82ba
NC
357 return prt_n (buf, info, mytxt);
358}
359
360static int
6655dba2 361rst (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
362{
363 info->fprintf_func (info->stream, txt, buf->data[0] & 0x38);
364 buf->n_used = buf->n_fetch;
365 return buf->n_used;
366}
367
9fc0b501 368
3c9b82ba 369static int
6655dba2 370cis (struct buffer *buf, disassemble_info * info, const char *txt ATTRIBUTE_UNUSED)
3c9b82ba
NC
371{
372 static char * opar[] = { "ld", "cp", "in", "out" };
373 char * op;
374 char c;
375
376 c = buf->data[1];
377 op = ((0x13 & c) == 0x13) ? "ot" : (opar[c & 3]);
378 info->fprintf_func (info->stream,
379 "%s%c%s", op,
380 (c & 0x08) ? 'd' : 'i',
381 (c & 0x10) ? "r" : "");
382 buf->n_used = 2;
383 return buf->n_used;
384}
385
386static int
6655dba2
SB
387cism (struct buffer *buf, disassemble_info * info, const char *txt ATTRIBUTE_UNUSED)
388{
389 static char * opar[] = { "in%cm%s", "ot%cm%s" };
390 char * op;
391 char c;
392
393 c = buf->data[1];
394 op = opar[c & 1];
395 info->fprintf_func (info->stream,
396 op,
397 (c & 0x08) ? 'd' : 'i',
398 (c & 0x10) ? "r" : "");
399 buf->n_used = 2;
400 return buf->n_used;
401}
402
6655dba2
SB
403static int
404dump (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
405{
406 int i;
407
408 info->fprintf_func (info->stream, "defb ");
409 for (i = 0; txt[i]; ++i)
410 info->fprintf_func (info->stream, i ? ", 0x%02x" : "0x%02x",
411 (unsigned char) buf->data[i]);
412 buf->n_used = i;
413 return buf->n_used;
414}
9fc0b501 415
3c9b82ba
NC
416/* Table to disassemble machine codes with prefix 0xED. */
417struct tab_elt opc_ed[] =
418{
9fc0b501
SB
419 { 0x30, 0xFF, prt, "mul d,e", INSS_Z80N },
420 { 0x31, 0xFF, prt, "add hl,a", INSS_Z80N },
b8ba1385 421 { 0x31, 0xFF, prt, "ld iy,(hl)", INSS_EZ80 },
9fc0b501 422 { 0x30, 0xFE, dump, "xx", INSS_ALL }, /* do not move this line */
6655dba2
SB
423 { 0x00, 0xC7, prt_r_n, "in0 %s,(0x%%02x)", INSS_Z180|INSS_EZ80 },
424 { 0x01, 0xC7, prt_r_n, "out0 (0x%%02x),%s", INSS_Z180|INSS_EZ80 },
425 { 0x32, 0xFF, prt_d, "lea ix,ix%+d", INSS_EZ80 },
426 { 0x33, 0xFF, prt_d, "lea iy,iy%+d", INSS_EZ80 },
427 { 0x02, 0xCF, prt_rr_d, "lea %s,ix%%+d", INSS_EZ80 },
428 { 0x03, 0xCF, prt_rr_d, "lea %s,iy%%+d", INSS_EZ80 },
429 { 0x04, 0xC7, prt_r, "tst %s", INSS_Z180},
430 { 0x04, 0xC7, prt_r, "tst a,%s", INSS_EZ80 },
431 { 0x07, 0xFF, prt, "ld bc,(hl)", INSS_EZ80 },
b8ba1385 432 { 0x3F, 0xFF, prt, "ld (hl),ix", INSS_EZ80 },
6655dba2
SB
433 { 0x0F, 0xCF, prt_rr, "ld (hl),", INSS_EZ80 },
434 { 0x17, 0xFF, prt, "ld de,(hl)", INSS_EZ80 },
9fc0b501
SB
435 { 0x23, 0xFF, prt, "swapnib", INSS_Z80N },
436 { 0x24, 0xFF, prt, "mirror", INSS_Z80N },
6655dba2 437 { 0x27, 0xFF, prt, "ld hl,(hl)", INSS_EZ80 },
9fc0b501
SB
438 { 0x27, 0xFF, prt_n, "test 0x%02x", INSS_Z80N },
439 { 0x28, 0xFF, prt, "bsla de,b", INSS_Z80N },
440 { 0x29, 0xFF, prt, "bsra de,b", INSS_Z80N },
441 { 0x2A, 0xFF, prt, "bsrl de,b", INSS_Z80N },
442 { 0x2B, 0xFF, prt, "bsrf de,b", INSS_Z80N },
443 { 0x2C, 0xFF, prt, "bslc de,b", INSS_Z80N },
444 { 0x32, 0xFF, prt, "add de,a", INSS_Z80N },
445 { 0x33, 0xFF, prt, "add bc,a", INSS_Z80N },
446 { 0x34, 0xFF, prt_nn, "add hl,0x%04x", INSS_Z80N },
447 { 0x35, 0xFF, prt_nn, "add de,0x%04x", INSS_Z80N },
448 { 0x36, 0xFF, prt_nn, "add bc,0x%04x", INSS_Z80N },
6655dba2
SB
449 { 0x37, 0xFF, prt, "ld ix,(hl)", INSS_EZ80 },
450 { 0x3E, 0xFF, prt, "ld (hl),iy", INSS_EZ80 },
9fc0b501 451 { 0x70, 0xFF, prt, "in f,(c)", INSS_Z80 | INSS_R800 | INSS_Z80N },
6655dba2
SB
452 { 0x70, 0xFF, dump, "xx", INSS_ALL },
453 { 0x40, 0xC7, prt_r, "in %s,(bc)", INSS_EZ80 },
454 { 0x40, 0xC7, prt_r, "in %s,(c)", INSS_ALL },
9fc0b501
SB
455 { 0x71, 0xFF, prt, "out (c),0", INSS_Z80 | INSS_Z80N },
456 { 0x71, 0xFF, dump, "xx", INSS_ALL },
6655dba2
SB
457 { 0x41, 0xC7, prt_r, "out (bc),%s", INSS_EZ80 },
458 { 0x41, 0xC7, prt_r, "out (c),%s", INSS_ALL },
459 { 0x42, 0xCF, prt_rr, "sbc hl,", INSS_ALL },
460 { 0x43, 0xCF, prt_rr_nn, "ld (0x%%04x),%s", INSS_ALL },
461 { 0x44, 0xFF, prt, "neg", INSS_ALL },
462 { 0x45, 0xFF, prt, "retn", INSS_ALL },
463 { 0x46, 0xFF, prt, "im 0", INSS_ALL },
464 { 0x47, 0xFF, prt, "ld i,a", INSS_ALL },
465 { 0x4A, 0xCF, prt_rr, "adc hl,", INSS_ALL },
466 { 0x4B, 0xCF, prt_rr_nn, "ld %s,(0x%%04x)", INSS_ALL },
467 { 0x4C, 0xCF, prt_rr, "mlt ", INSS_Z180|INSS_EZ80 },
468 { 0x4D, 0xFF, prt, "reti", INSS_ALL },
469 { 0x4F, 0xFF, prt, "ld r,a", INSS_ALL },
470 { 0x54, 0xFF, prt_d, "lea ix,iy%+d", INSS_EZ80 },
471 { 0x55, 0xFF, prt_d, "lea iy,ix%+d", INSS_EZ80 },
472 { 0x56, 0xFF, prt, "im 1", INSS_ALL },
473 { 0x57, 0xFF, prt, "ld a,i", INSS_ALL },
474 { 0x5E, 0xFF, prt, "im 2", INSS_ALL },
475 { 0x5F, 0xFF, prt, "ld a,r", INSS_ALL },
476 { 0x64, 0xFF, prt_n, "tst 0x%02x", INSS_Z180 },
477 { 0x64, 0xFF, prt_n, "tst a,0x%02x", INSS_EZ80 },
478 { 0x65, 0xFF, prt_d, "pea ix%+d", INSS_EZ80 },
479 { 0x66, 0xFF, prt_d, "pea iy%+d", INSS_EZ80 },
480 { 0x67, 0xFF, prt, "rrd", INSS_ALL },
9fc0b501
SB
481 { 0x6D, 0xFF, prt, "ld mb,a", INSS_EZ80 },
482 { 0x6E, 0xFF, prt, "ld a,mb", INSS_EZ80 },
6655dba2
SB
483 { 0x6F, 0xFF, prt, "rld", INSS_ALL },
484 { 0x74, 0xFF, prt_n, "tstio 0x%02x", INSS_Z180|INSS_EZ80 },
485 { 0x76, 0xFF, prt, "slp", INSS_Z180|INSS_EZ80 },
9fc0b501
SB
486 { 0x7D, 0xFF, prt, "stmix", INSS_EZ80 },
487 { 0x7E, 0xFF, prt, "rsmix", INSS_EZ80 },
6655dba2 488 { 0x82, 0xE6, cism, "", INSS_Z180|INSS_EZ80 },
68e52bc7 489 { 0x84, 0xFF, prt, "ini2", INSS_EZ80 },
9fc0b501 490 { 0x8A, 0xFF, prt_n_n, "push 0x%02x%%02x", INSS_Z80N },
68e52bc7 491 { 0x8C, 0xFF, prt, "ind2", INSS_EZ80 },
9fc0b501
SB
492 { 0x90, 0xFF, prt, "outinb", INSS_Z80N },
493 { 0x91, 0xFF, prt_n_n, "nextreg 0x%02x,0x%%02x", INSS_Z80N },
494 { 0x92, 0xFF, prt_n, "nextreg 0x%02x,a", INSS_Z80N },
495 { 0x93, 0xFF, prt, "pixeldn", INSS_Z80N },
68e52bc7 496 { 0x94, 0xFF, prt, "ini2r", INSS_EZ80 },
9fc0b501
SB
497 { 0x94, 0xFF, prt, "pixelad", INSS_Z80N },
498 { 0x95, 0xFF, prt, "setae", INSS_Z80N },
499 { 0x98, 0xFF, prt, "jp (c)", INSS_Z80N },
68e52bc7 500 { 0x9c, 0xFF, prt, "ind2r", INSS_EZ80 },
6655dba2 501 { 0xA0, 0xE4, cis, "", INSS_ALL },
68e52bc7 502 { 0xA4, 0xFF, prt, "outi2", INSS_EZ80 },
9fc0b501 503 { 0xA4, 0xFF, prt, "ldix", INSS_Z80N },
68e52bc7 504 { 0xAC, 0xFF, prt, "outd2", INSS_EZ80 },
9fc0b501
SB
505 { 0xAC, 0xFF, prt, "lddx", INSS_Z80N },
506 { 0xA5, 0xFF, prt, "ldws", INSS_Z80N },
68e52bc7 507 { 0xB4, 0xFF, prt, "oti2r", INSS_EZ80 },
9fc0b501
SB
508 { 0xB4, 0xFF, prt, "ldirx", INSS_Z80N },
509 { 0xB7, 0xFF, prt, "ldpirx", INSS_Z80N },
68e52bc7 510 { 0xBC, 0xFF, prt, "otd2r", INSS_EZ80 },
9fc0b501 511 { 0xBC, 0xFF, prt, "lddrx", INSS_Z80N },
6655dba2
SB
512 { 0xC2, 0xFF, prt, "inirx", INSS_EZ80 },
513 { 0xC3, 0xFF, prt, "otirx", INSS_EZ80 },
9fc0b501 514 { 0xC7, 0xFF, prt, "ld i,hl", INSS_EZ80 },
6655dba2
SB
515 { 0xCA, 0xFF, prt, "indrx", INSS_EZ80 },
516 { 0xCB, 0xFF, prt, "otdrx", INSS_EZ80 },
517 { 0xC3, 0xFF, prt, "muluw hl,bc", INSS_R800 },
518 { 0xC5, 0xE7, prt_r, "mulub a,%s", INSS_R800 },
9fc0b501 519 { 0xD7, 0xFF, prt, "ld hl,i", INSS_EZ80 },
6655dba2
SB
520 { 0xF3, 0xFF, prt, "muluw hl,sp", INSS_R800 },
521 { 0x00, 0x00, dump, "xx", INSS_ALL }
3c9b82ba
NC
522};
523
524static int
6655dba2
SB
525pref_ed (struct buffer *buf, disassemble_info *info,
526 const char *txt ATTRIBUTE_UNUSED)
3c9b82ba
NC
527{
528 struct tab_elt *p;
529
40c75bc8 530 if (fetch_data (buf, info, 1))
3c9b82ba 531 {
40c75bc8 532 for (p = opc_ed; p->val != (buf->data[1] & p->mask) || !mach_inst (buf, p); ++p)
6655dba2 533 ;
3c9b82ba
NC
534 p->fp (buf, info, p->text);
535 }
536 else
537 buf->n_used = -1;
538
539 return buf->n_used;
540}
541\f
542/* Instruction names for the instructions addressing single bits. */
543static char *cb1_str[] = { "", "bit", "res", "set"};
544/* Instruction names for shifts and rotates. */
545static char *cb2_str[] =
546{
547 "rlc", "rrc", "rl", "rr", "sla", "sra", "sli", "srl"
548};
549
550static int
6655dba2
SB
551pref_cb (struct buffer *buf, disassemble_info *info,
552 const char *txt ATTRIBUTE_UNUSED)
3c9b82ba 553{
6655dba2
SB
554 const char *op_txt;
555 int idx;
3c9b82ba
NC
556 if (fetch_data (buf, info, 1))
557 {
558 buf->n_used = 2;
559 if ((buf->data[1] & 0xc0) == 0)
6655dba2
SB
560 {
561 idx = (buf->data[1] >> 3) & 7;
562 if ((buf->inss & INSS_GBZ80) && (idx == 6))
563 op_txt = "swap";
564 else
565 op_txt = cb2_str[idx];
566 info->fprintf_func (info->stream, "%s %s",
567 op_txt,
568 r_str[buf->data[1] & 7]);
569 }
3c9b82ba
NC
570 else
571 info->fprintf_func (info->stream, "%s %d,%s",
572 cb1_str[(buf->data[1] >> 6) & 3],
573 (buf->data[1] >> 3) & 7,
574 r_str[buf->data[1] & 7]);
575 }
576 else
577 buf->n_used = -1;
578
579 return buf->n_used;
580}
9fc0b501 581
3c9b82ba 582static int
6655dba2 583addvv (struct buffer * buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
584{
585 info->fprintf_func (info->stream, "add %s,%s", txt, txt);
586
587 return buf->n_used = buf->n_fetch;
588}
589
590static int
6655dba2 591ld_v_v (struct buffer * buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
592{
593 char mytxt[TXTSIZ];
594
595 snprintf (mytxt, TXTSIZ, "ld %s%%s,%s%%s", txt, txt);
596 return ld_r_r (buf, info, mytxt);
597}
598
599static int
6655dba2 600prt_d_n (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba 601{
6655dba2 602 char mytxt[TXTSIZ];
3c9b82ba 603 int d;
9e919b5f 604 signed char *p;
3c9b82ba 605
c9021189 606 p = buf->data + buf->n_fetch;
3c9b82ba
NC
607
608 if (fetch_data (buf, info, 1))
609 {
610 d = p[0];
6655dba2
SB
611 snprintf (mytxt, TXTSIZ, txt, d);
612 return prt_n (buf, info, mytxt);
3c9b82ba
NC
613 }
614 else
615 buf->n_used = -1;
616
617 return buf->n_used;
618}
619
620static int
6655dba2 621arit_d (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
622{
623 char mytxt[TXTSIZ];
6655dba2
SB
624 signed char c;
625 const char * const *arit;
3c9b82ba 626
6655dba2
SB
627 arit = (buf->inss & INSS_EZ80) ? arit_str_ez80 : arit_str;
628 c = buf->data[buf->n_fetch - 1];
629 snprintf (mytxt, TXTSIZ, txt, arit[(c >> 3) & 7]);
630 return prt_d (buf, info, mytxt);
3c9b82ba
NC
631}
632
633static int
6655dba2 634ld_r_d (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
635{
636 char mytxt[TXTSIZ];
9e919b5f 637 signed char c;
3c9b82ba
NC
638
639 c = buf->data[buf->n_fetch - 1];
6655dba2 640 snprintf (mytxt, TXTSIZ, txt, r_str[(c >> 3) & 7]);
3c9b82ba
NC
641 return prt_d (buf, info, mytxt);
642}
643
644static int
40c75bc8 645ld_d_r (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
646{
647 char mytxt[TXTSIZ];
9e919b5f 648 signed char c;
3c9b82ba
NC
649
650 c = buf->data[buf->n_fetch - 1];
6655dba2 651 snprintf (mytxt, TXTSIZ, txt, r_str[c & 7]);
3c9b82ba
NC
652 return prt_d (buf, info, mytxt);
653}
654
655static int
40c75bc8 656ld_ii_ii (struct buffer *buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
657{
658 char mytxt[TXTSIZ];
9e919b5f 659 signed char c;
6655dba2
SB
660 int p;
661 static const char *ii[2] = { "ix", "iy" };
3c9b82ba 662
bce58db4 663 p = (buf->data[buf->n_fetch - 2] == (signed char) 0xdd) ? 0 : 1;
3c9b82ba 664 c = buf->data[buf->n_fetch - 1];
6655dba2
SB
665 if ((c & 0x07) != 0x07)
666 p = 1 - p; /* 0 -> 1, 1 -> 0 */
667 snprintf (mytxt, TXTSIZ, txt, ii[p]);
3c9b82ba
NC
668 return prt_d (buf, info, mytxt);
669}
670
671static int
6655dba2 672pref_xd_cb (struct buffer * buf, disassemble_info * info, const char *txt)
3c9b82ba
NC
673{
674 if (fetch_data (buf, info, 2))
675 {
676 int d;
677 char arg[TXTSIZ];
9e919b5f 678 signed char *p;
3c9b82ba
NC
679
680 buf->n_used = 4;
681 p = buf->data;
682 d = p[2];
683
684 if (((p[3] & 0xC0) == 0x40) || ((p[3] & 7) == 0x06))
9e919b5f 685 snprintf (arg, TXTSIZ, "(%s%+d)", txt, d);
3c9b82ba 686 else
9e919b5f 687 snprintf (arg, TXTSIZ, "(%s%+d),%s", txt, d, r_str[p[3] & 7]);
3c9b82ba
NC
688
689 if ((p[3] & 0xc0) == 0)
690 info->fprintf_func (info->stream, "%s %s",
691 cb2_str[(buf->data[3] >> 3) & 7],
692 arg);
693 else
694 info->fprintf_func (info->stream, "%s %d,%s",
695 cb1_str[(buf->data[3] >> 6) & 3],
696 (buf->data[3] >> 3) & 7,
697 arg);
698 }
699 else
700 buf->n_used = -1;
701
702 return buf->n_used;
703}
704\f
705/* Table to disassemble machine codes with prefix 0xDD or 0xFD. */
706static struct tab_elt opc_ind[] =
707{
6655dba2
SB
708 { 0x07, 0xFF, prt_d, "ld bc,(%s%%+d)", INSS_EZ80 },
709 { 0x0F, 0xFF, prt_d, "ld (%s%%+d),bc", INSS_EZ80 },
710 { 0x17, 0xFF, prt_d, "ld de,(%s%%+d)", INSS_EZ80 },
711 { 0x1F, 0xFF, prt_d, "ld (%s%%+d),de", INSS_EZ80 },
712 { 0x24, 0xF7, prt_r, "inc %s%%s", INSS_ALL },
713 { 0x25, 0xF7, prt_r, "dec %s%%s", INSS_ALL },
714 { 0x26, 0xF7, ld_r_n, "ld %s%%s,0x%%%%02x", INSS_ALL },
715 { 0x27, 0xFF, prt_d, "ld hl,(%s%%+d)", INSS_EZ80 },
716 { 0x2F, 0xFF, prt_d, "ld (%s%%+d),hl", INSS_EZ80 },
717 { 0x21, 0xFF, prt_nn, "ld %s,0x%%04x", INSS_ALL },
718 { 0x22, 0xFF, prt_nn, "ld (0x%%04x),%s", INSS_ALL },
719 { 0x2A, 0xFF, prt_nn, "ld %s,(0x%%04x)", INSS_ALL },
720 { 0x23, 0xFF, prt, "inc %s", INSS_ALL },
721 { 0x2B, 0xFF, prt, "dec %s", INSS_ALL },
722 { 0x29, 0xFF, addvv, "%s", INSS_ALL },
723 { 0x31, 0xFF, ld_ii_ii, "ld %%s,(%s%%%%+d)", INSS_EZ80 },
724 { 0x37, 0xFF, ld_ii_ii, "ld %%s,(%s%%%%+d)", INSS_EZ80 },
725 { 0x3E, 0xFE, ld_ii_ii, "ld (%s%%%%+d),%%s", INSS_EZ80 },
726 { 0x09, 0xCF, prt_rr, "add %s,", INSS_ALL },
727 { 0x34, 0xFF, prt_d, "inc (%s%%+d)", INSS_ALL },
728 { 0x35, 0xFF, prt_d, "dec (%s%%+d)", INSS_ALL },
729 { 0x36, 0xFF, prt_d_n, "ld (%s%%+d),0x%%%%02x", INSS_ALL },
730
731 { 0x76, 0xFF, dump, "h", INSS_ALL },
732 { 0x46, 0xC7, ld_r_d, "ld %%s,(%s%%%%+d)", INSS_ALL },
733 { 0x70, 0xF8, ld_d_r, "ld (%s%%%%+d),%%s", INSS_ALL },
734 { 0x64, 0xF6, ld_v_v, "%s", INSS_ALL },
735 { 0x60, 0xF0, ld_r_r, "ld %s%%s,%%s", INSS_ALL },
736 { 0x44, 0xC6, ld_r_r, "ld %%s,%s%%s", INSS_ALL },
737
738 { 0x86, 0xC7, arit_d, "%%s(%s%%%%+d)", INSS_ALL },
739 { 0x84, 0xC6, arit_r, "%%s%s%%s", INSS_ALL },
740
741 { 0xE1, 0xFF, prt, "pop %s", INSS_ALL },
742 { 0xE5, 0xFF, prt, "push %s", INSS_ALL },
743 { 0xCB, 0xFF, pref_xd_cb, "%s", INSS_ALL },
744 { 0xE3, 0xFF, prt, "ex (sp),%s", INSS_ALL },
745 { 0xE9, 0xFF, prt, "jp (%s)", INSS_ALL },
746 { 0xF9, 0xFF, prt, "ld sp,%s", INSS_ALL },
747 { 0x00, 0x00, dump, "?", INSS_ALL },
3c9b82ba
NC
748} ;
749
750static int
6655dba2 751pref_ind (struct buffer *buf, disassemble_info *info, const char *txt)
3c9b82ba
NC
752{
753 if (fetch_data (buf, info, 1))
754 {
755 char mytxt[TXTSIZ];
756 struct tab_elt *p;
757
6655dba2
SB
758 for (p = opc_ind; p->val != (buf->data[1] & p->mask) || !mach_inst (buf, p); ++p)
759 ;
3c9b82ba
NC
760 snprintf (mytxt, TXTSIZ, p->text, txt);
761 p->fp (buf, info, mytxt);
762 }
763 else
764 buf->n_used = -1;
765
766 return buf->n_used;
767}
768
6655dba2
SB
769static int
770print_insn_z80_buf (struct buffer *buf, disassemble_info *info);
771
772static int
660e62b1 773suffix (struct buffer *buf, disassemble_info *info, const char *txt)
6655dba2 774{
6655dba2
SB
775 char mybuf[TXTSIZ*4];
776 fprintf_ftype old_fprintf;
777 void *old_stream;
778 char *p;
779
6655dba2
SB
780 switch (txt[2])
781 {
782 case 'l': /* SIL or LIL */
660e62b1 783 buf->nn_len = 3;
6655dba2
SB
784 break;
785 case 's': /* SIS or LIS */
660e62b1 786 buf->nn_len = 2;
6655dba2
SB
787 break;
788 default:
660e62b1
AM
789 abort ();
790 }
791 if (!fetch_data (buf, info, 1)
792 || buf->data[1] == 0x40
793 || buf->data[1] == 0x49
794 || buf->data[1] == 0x52
795 || buf->data[1] == 0x5b)
796 {
797 /* Double prefix, or end of data. */
7a6bf3be 798 info->fprintf_func (info->stream, ".db 0x%02x ; %s", (unsigned)buf->data[0], txt);
660e62b1
AM
799 buf->n_used = 1;
800 return buf->n_used;
6655dba2 801 }
660e62b1 802
6655dba2
SB
803 old_fprintf = info->fprintf_func;
804 old_stream = info->stream;
660e62b1 805 info->fprintf_func = (fprintf_ftype) &sprintf;
6655dba2 806 info->stream = mybuf;
a18cd0ca 807 mybuf[0] = 0;
660e62b1
AM
808 buf->base++;
809 if (print_insn_z80_buf (buf, info) >= 0)
810 buf->n_used++;
6655dba2
SB
811 info->fprintf_func = old_fprintf;
812 info->stream = old_stream;
813
660e62b1
AM
814 for (p = mybuf; *p; ++p)
815 if (*p == ' ')
816 break;
817 if (*p)
6655dba2 818 {
660e62b1
AM
819 *p++ = '\0';
820 info->fprintf_func (info->stream, "%s.%s %s", mybuf, txt, p);
6655dba2 821 }
660e62b1
AM
822 else
823 info->fprintf_func (info->stream, "%s.%s", mybuf, txt);
824 return buf->n_used;
6655dba2
SB
825}
826
3c9b82ba 827/* Table to disassemble machine codes without prefix. */
9fc0b501
SB
828static const struct tab_elt
829opc_main[] =
3c9b82ba 830{
6655dba2
SB
831 { 0x00, 0xFF, prt, "nop", INSS_ALL },
832 { 0x01, 0xCF, prt_rr_nn, "ld %s,0x%%04x", INSS_ALL },
833 { 0x02, 0xFF, prt, "ld (bc),a", INSS_ALL },
834 { 0x03, 0xCF, prt_rr, "inc ", INSS_ALL },
835 { 0x04, 0xC7, prt_r, "inc %s", INSS_ALL },
836 { 0x05, 0xC7, prt_r, "dec %s", INSS_ALL },
837 { 0x06, 0xC7, ld_r_n, "ld %s,0x%%02x", INSS_ALL },
838 { 0x07, 0xFF, prt, "rlca", INSS_ALL },
839 { 0x08, 0xFF, prt, "ex af,af'", ~INSS_GBZ80 },
840 { 0x09, 0xCF, prt_rr, "add hl,", INSS_ALL },
841 { 0x0A, 0xFF, prt, "ld a,(bc)", INSS_ALL },
842 { 0x0B, 0xCF, prt_rr, "dec ", INSS_ALL },
843 { 0x0F, 0xFF, prt, "rrca", INSS_ALL },
844 { 0x10, 0xFF, prt_e, "djnz ", ~INSS_GBZ80 },
845 { 0x12, 0xFF, prt, "ld (de),a", INSS_ALL },
846 { 0x17, 0xFF, prt, "rla", INSS_ALL },
847 { 0x18, 0xFF, prt_e, "jr ", INSS_ALL },
848 { 0x1A, 0xFF, prt, "ld a,(de)", INSS_ALL },
849 { 0x1F, 0xFF, prt, "rra", INSS_ALL },
850 { 0x20, 0xE7, jr_cc, "jr %s,", INSS_ALL },
851 { 0x22, 0xFF, prt_nn, "ld (0x%04x),hl", ~INSS_GBZ80 },
852 { 0x27, 0xFF, prt, "daa", INSS_ALL },
853 { 0x2A, 0xFF, prt_nn, "ld hl,(0x%04x)", ~INSS_GBZ80 },
854 { 0x2F, 0xFF, prt, "cpl", INSS_ALL },
855 { 0x32, 0xFF, prt_nn, "ld (0x%04x),a", INSS_ALL },
856 { 0x37, 0xFF, prt, "scf", INSS_ALL },
857 { 0x3A, 0xFF, prt_nn, "ld a,(0x%04x)", INSS_ALL },
858 { 0x3F, 0xFF, prt, "ccf", INSS_ALL },
859
860 { 0x76, 0xFF, prt, "halt", INSS_ALL },
861
862 { 0x40, 0xFF, suffix, "sis", INSS_EZ80 },
863 { 0x49, 0xFF, suffix, "lis", INSS_EZ80 },
864 { 0x52, 0xFF, suffix, "sil", INSS_EZ80 },
865 { 0x5B, 0xFF, suffix, "lil", INSS_EZ80 },
866
867 { 0x40, 0xC0, ld_r_r, "ld %s,%s", INSS_ALL},
868
869 { 0x80, 0xC0, arit_r, "%s%s", INSS_ALL },
870
871 { 0xC0, 0xC7, prt_cc, "ret ", INSS_ALL },
872 { 0xC1, 0xCF, pop_rr, "pop", INSS_ALL },
873 { 0xC2, 0xC7, jp_cc_nn, "jp ", INSS_ALL },
874 { 0xC3, 0xFF, prt_nn, "jp 0x%04x", INSS_ALL },
875 { 0xC4, 0xC7, jp_cc_nn, "call ", INSS_ALL },
876 { 0xC5, 0xCF, pop_rr, "push", INSS_ALL },
877 { 0xC6, 0xC7, arit_n, "%s0x%%02x", INSS_ALL },
878 { 0xC7, 0xC7, rst, "rst 0x%02x", INSS_ALL },
879 { 0xC9, 0xFF, prt, "ret", INSS_ALL },
880 { 0xCB, 0xFF, pref_cb, "", INSS_ALL },
881 { 0xCD, 0xFF, prt_nn, "call 0x%04x", INSS_ALL },
882 { 0xD3, 0xFF, prt_n, "out (0x%02x),a", ~INSS_GBZ80 },
883 { 0xD9, 0xFF, prt, "exx", ~INSS_GBZ80 },
884 { 0xDB, 0xFF, prt_n, "in a,(0x%02x)", ~INSS_GBZ80 },
885 { 0xDD, 0xFF, pref_ind, "ix", ~INSS_GBZ80 },
886 { 0xE3, 0xFF, prt, "ex (sp),hl", ~INSS_GBZ80 },
887 { 0xE9, 0xFF, prt, "jp (hl)", INSS_ALL },
888 { 0xEB, 0xFF, prt, "ex de,hl", ~INSS_GBZ80 },
889 { 0xED, 0xFF, pref_ed, "", ~INSS_GBZ80 },
890 { 0xF3, 0xFF, prt, "di", INSS_ALL },
9fc0b501 891 { 0xF9, 0xFF, prt, "ld sp,hl", INSS_ALL },
6655dba2
SB
892 { 0xFB, 0xFF, prt, "ei", INSS_ALL },
893 { 0xFD, 0xFF, pref_ind, "iy", ~INSS_GBZ80 },
894 { 0x00, 0x00, prt, "????", INSS_ALL },
3c9b82ba
NC
895} ;
896
9fc0b501
SB
897/* Separate GBZ80 main opcode table due to many differences */
898static const struct tab_elt
899opc_main_gbz80[] =
900{
901 { 0x00, 0xFF, prt,"nop", INSS_ALL },
902 { 0x01, 0xCF, prt_rr_nn, "ld %s,0x%%04x", INSS_ALL },
903 { 0x02, 0xFF, prt, "ld (bc),a", INSS_ALL },
904 { 0x03, 0xCF, prt_rr, "inc ", INSS_ALL },
905 { 0x04, 0xC7, prt_r, "inc %s", INSS_ALL },
906 { 0x05, 0xC7, prt_r, "dec %s", INSS_ALL },
907 { 0x06, 0xC7, ld_r_n, "ld %s,0x%%02x", INSS_ALL },
908 { 0x07, 0xFF, prt, "rlca", INSS_ALL },
909 { 0x08, 0xFF, prt_nn, "ld (0x%04x),sp", INSS_GBZ80 },
910 { 0x09, 0xCF, prt_rr, "add hl,", INSS_ALL },
911 { 0x0A, 0xFF, prt, "ld a,(bc)", INSS_ALL },
912 { 0x0B, 0xCF, prt_rr, "dec ", INSS_ALL },
913 { 0x0F, 0xFF, prt, "rrca", INSS_ALL },
914 { 0x10, 0xFF, prt, "stop", INSS_GBZ80 },
915 { 0x12, 0xFF, prt, "ld (de),a", INSS_ALL },
916 { 0x17, 0xFF, prt, "rla", INSS_ALL },
917 { 0x18, 0xFF, prt_e, "jr ", INSS_ALL },
918 { 0x1A, 0xFF, prt, "ld a,(de)", INSS_ALL },
919 { 0x1F, 0xFF, prt, "rra", INSS_ALL },
920 { 0x20, 0xE7, jr_cc, "jr %s,", INSS_ALL },
921 { 0x22, 0xFF, prt, "ld (hl+),a", INSS_GBZ80 },
922 { 0x27, 0xFF, prt, "daa", INSS_ALL },
923 { 0x2A, 0xFF, prt, "ld a,(hl+)", INSS_GBZ80 },
924 { 0x2F, 0xFF, prt, "cpl", INSS_ALL },
925 { 0x32, 0xFF, prt, "ld (hl-),a", INSS_GBZ80 },
926 { 0x37, 0xFF, prt, "scf", INSS_ALL },
927 { 0x3A, 0xFF, prt, "ld a,(hl-)", INSS_GBZ80 },
928 { 0x3F, 0xFF, prt, "ccf", INSS_ALL },
929 { 0x76, 0xFF, prt, "halt", INSS_ALL },
930 { 0x40, 0xC0, ld_r_r, "ld %s,%s", INSS_ALL},
931 { 0x80, 0xC0, arit_r, "%s%s", INSS_ALL },
932 { 0xC0, 0xE7, prt_cc, "ret ", INSS_ALL },
933 { 0xC1, 0xCF, pop_rr, "pop", INSS_ALL },
934 { 0xC2, 0xE7, jp_cc_nn, "jp ", INSS_ALL },
935 { 0xC3, 0xFF, prt_nn, "jp 0x%04x", INSS_ALL },
936 { 0xC4, 0xE7, jp_cc_nn, "call ", INSS_ALL },
937 { 0xC5, 0xCF, pop_rr, "push", INSS_ALL },
938 { 0xC6, 0xC7, arit_n, "%s0x%%02x", INSS_ALL },
939 { 0xC7, 0xC7, rst, "rst 0x%02x", INSS_ALL },
940 { 0xC9, 0xFF, prt, "ret", INSS_ALL },
941 { 0xCB, 0xFF, pref_cb, "", INSS_ALL },
942 { 0xCD, 0xFF, prt_nn, "call 0x%04x", INSS_ALL },
943 { 0xD9, 0xFF, prt, "reti", INSS_GBZ80 },
944 { 0xE0, 0xFF, prt_n, "ldh (0x%02x),a", INSS_GBZ80 },
945 { 0xE2, 0xFF, prt, "ldh (c),a", INSS_GBZ80 },
946 { 0xE8, 0xFF, prt_d, "add sp,%d", INSS_GBZ80 },
947 { 0xE9, 0xFF, prt, "jp (hl)", INSS_ALL },
948 { 0xEA, 0xFF, prt_nn, "ld (0x%04x),a", INSS_GBZ80 },
949 { 0xF0, 0xFF, prt_n, "ldh a,(0x%02x)", INSS_GBZ80 },
950 { 0xF2, 0xFF, prt, "ldh a,(c)", INSS_GBZ80 },
951 { 0xF3, 0xFF, prt, "di", INSS_ALL },
952 { 0xF8, 0xFF, prt_d, "ldhl sp,%d", INSS_GBZ80 },
953 { 0xF9, 0xFF, prt, "ld sp,hl", INSS_ALL },
954 { 0xFA, 0xFF, prt_nn, "ld a,(0x%04x)", INSS_GBZ80 },
955 { 0xFB, 0xFF, prt, "ei", INSS_ALL },
956 { 0x00, 0x00, dump, "?", INSS_ALL },
957} ;
958
3c9b82ba
NC
959int
960print_insn_z80 (bfd_vma addr, disassemble_info * info)
961{
962 struct buffer buf;
3c9b82ba
NC
963
964 buf.base = addr;
6655dba2
SB
965 buf.inss = 1 << info->mach;
966 buf.nn_len = info->mach == bfd_mach_ez80_adl ? 3 : 2;
967 info->bytes_per_line = (buf.inss & INSS_EZ80) ? 6 : 4; /* <ss pp oo nn mm MM> OR <pp oo nn mm> */
3c9b82ba 968
6655dba2
SB
969 return print_insn_z80_buf (&buf, info);
970}
971
972static int
973print_insn_z80_buf (struct buffer *buf, disassemble_info *info)
974{
9fc0b501 975 const struct tab_elt *p;
6655dba2 976
660e62b1
AM
977 buf->n_fetch = 0;
978 buf->n_used = 0;
6655dba2 979 if (! fetch_data (buf, info, 1))
3c9b82ba
NC
980 return -1;
981
9fc0b501
SB
982 p = (buf->inss & INSS_GBZ80) ? opc_main_gbz80 : opc_main;
983
984 for (; p->val != (buf->data[0] & p->mask) || !mach_inst (buf, p); ++p)
3c9b82ba 985 ;
6655dba2 986 p->fp (buf, info, p->text);
3c9b82ba 987
6655dba2 988 return buf->n_used;
3c9b82ba 989}
This page took 0.721236 seconds and 4 git commands to generate.