summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z180/z180dasm.cpp
blob: 835c620770dd2fbda021857f8514f112a05d4bb6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
/*****************************************************************************
 *
 *   Portable Z8x180 disassembler
 *
 *****************************************************************************/

#include "emu.h"
#include "z180dasm.h"

const char *const z180_disassembler::s_mnemonic[] = {
	"adc"  ,"add"  ,"and"  ,"bit"  ,"call" ,"ccf"  ,"cp"   ,"cpd"  ,
	"cpdr" ,"cpi"  ,"cpir" ,"cpl"  ,"daa"  ,"db"   ,"dec"  ,"di"   ,
	"djnz" ,"ei"   ,"ex"   ,"exx"  ,"halt" ,"im"   ,"in"   ,"in0"  ,
	"inc"  ,"ind"  ,"indr" ,"ini"  ,"inir" ,"jp"   ,"jr"   ,"ld"   ,
	"ldd"  ,"lddr" ,"ldi"  ,"ldir" ,"mlt"  ,"neg"  ,"nop"  ,"or"   ,
	"otdm" ,"otdmr","otdr" ,"otim" ,"otimr","otir" ,"out"  ,"out0" ,
	"outd" ,"outi" ,"pop"  ,"push" ,"res"  ,"ret"  ,"reti" ,"retn" ,
	"rl"   ,"rla"  ,"rlc"  ,"rlca" ,"rld"  ,"rr"   ,"rra"  ,"rrc"  ,
	"rrca" ,"rrd"  ,"rst"  ,"sbc"  ,"scf"  ,"set"  ,"sla"  ,"sll"  ,
	"slp"  ,"sra"  ,"srl"  ,"sub"  ,"tst"  ,"tstio","xor "
};

const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx_cb[256]= {
	{zRLC,"b=Y"},   {zRLC,"c=Y"},   {zRLC,"d=Y"},   {zRLC,"e=Y"},
	{zRLC,"h=Y"},   {zRLC,"l=Y"},   {zRLC,"Y"},     {zRLC,"a=Y"},
	{zRRC,"b=Y"},   {zRRC,"c=Y"},   {zRRC,"d=Y"},   {zRRC,"e=Y"},
	{zRRC,"h=Y"},   {zRRC,"l=Y"},   {zRRC,"Y"},     {zRRC,"a=Y"},
	{zRL,"b=Y"},    {zRL,"c=Y"},    {zRL,"d=Y"},    {zRL,"e=Y"},
	{zRL,"h=Y"},    {zRL,"l=Y"},    {zRL,"Y"},      {zRL,"a=Y"},
	{zRR,"b=Y"},    {zRR,"c=Y"},    {zRR,"d=Y"},    {zRR,"e=Y"},
	{zRR,"h=Y"},    {zRR,"l=Y"},    {zRR,"Y"},      {zRR,"a=Y"},
	{zSLA,"b=Y"},   {zSLA,"c=Y"},   {zSLA,"d=Y"},   {zSLA,"e=Y"},
	{zSLA,"h=Y"},   {zSLA,"l=Y"},   {zSLA,"Y"},     {zSLA,"a=Y"},
	{zSRA,"b=Y"},   {zSRA,"c=Y"},   {zSRA,"d=Y"},   {zSRA,"e=Y"},
	{zSRA,"h=Y"},   {zSRA,"l=Y"},   {zSRA,"Y"},     {zSRA,"a=Y"},
	{zSLL,"b=Y"},   {zSLL,"c=Y"},   {zSLL,"d=Y"},   {zSLL,"e=Y"},
	{zSLL,"h=Y"},   {zSLL,"l=Y"},   {zSLL,"Y"},     {zSLL,"a=Y"},
	{zSRL,"b=Y"},   {zSRL,"c=Y"},   {zSRL,"d=Y"},   {zSRL,"e=Y"},
	{zSRL,"h=Y"},   {zSRL,"l=Y"},   {zSRL,"Y"},     {zSRL,"a=Y"},
	{zBIT,"b=0,Y"}, {zBIT,"c=0,Y"}, {zBIT,"d=0,Y"}, {zBIT,"e=0,Y"},
	{zBIT,"h=0,Y"}, {zBIT,"l=0,Y"}, {zBIT,"0,Y"},   {zBIT,"a=0,Y"},
	{zBIT,"b=1,Y"}, {zBIT,"c=1,Y"}, {zBIT,"d=1,Y"}, {zBIT,"e=1,Y"},
	{zBIT,"h=1,Y"}, {zBIT,"l=1,Y"}, {zBIT,"1,Y"},   {zBIT,"a=1,Y"},
	{zBIT,"b=2,Y"}, {zBIT,"c=2,Y"}, {zBIT,"d=2,Y"}, {zBIT,"e=2,Y"},
	{zBIT,"h=2,Y"}, {zBIT,"l=2,Y"}, {zBIT,"2,Y"},   {zBIT,"a=2,Y"},
	{zBIT,"b=3,Y"}, {zBIT,"c=3,Y"}, {zBIT,"d=3,Y"}, {zBIT,"e=3,Y"},
	{zBIT,"h=3,Y"}, {zBIT,"l=3,Y"}, {zBIT,"3,Y"},   {zBIT,"a=3,Y"},
	{zBIT,"b=4,Y"}, {zBIT,"c=4,Y"}, {zBIT,"d=4,Y"}, {zBIT,"e=4,Y"},
	{zBIT,"h=4,Y"}, {zBIT,"l=4,Y"}, {zBIT,"4,Y"},   {zBIT,"a=4,Y"},
	{zBIT,"b=5,Y"}, {zBIT,"c=5,Y"}, {zBIT,"d=5,Y"}, {zBIT,"e=5,Y"},
	{zBIT,"h=5,Y"}, {zBIT,"l=5,Y"}, {zBIT,"5,Y"},   {zBIT,"a=5,Y"},
	{zBIT,"b=6,Y"}, {zBIT,"c=6,Y"}, {zBIT,"d=6,Y"}, {zBIT,"e=6,Y"},
	{zBIT,"h=6,Y"}, {zBIT,"l=6,Y"}, {zBIT,"6,Y"},   {zBIT,"a=6,Y"},
	{zBIT,"b=7,Y"}, {zBIT,"c=7,Y"}, {zBIT,"d=7,Y"}, {zBIT,"e=7,Y"},
	{zBIT,"h=7,Y"}, {zBIT,"l=7,Y"}, {zBIT,"7,Y"},   {zBIT,"a=7,Y"},
	{zRES,"b=0,Y"}, {zRES,"c=0,Y"}, {zRES,"d=0,Y"}, {zRES,"e=0,Y"},
	{zRES,"h=0,Y"}, {zRES,"l=0,Y"}, {zRES,"0,Y"},   {zRES,"a=0,Y"},
	{zRES,"b=1,Y"}, {zRES,"c=1,Y"}, {zRES,"d=1,Y"}, {zRES,"e=1,Y"},
	{zRES,"h=1,Y"}, {zRES,"l=1,Y"}, {zRES,"1,Y"},   {zRES,"a=1,Y"},
	{zRES,"b=2,Y"}, {zRES,"c=2,Y"}, {zRES,"d=2,Y"}, {zRES,"e=2,Y"},
	{zRES,"h=2,Y"}, {zRES,"l=2,Y"}, {zRES,"2,Y"},   {zRES,"a=2,Y"},
	{zRES,"b=3,Y"}, {zRES,"c=3,Y"}, {zRES,"d=3,Y"}, {zRES,"e=3,Y"},
	{zRES,"h=3,Y"}, {zRES,"l=3,Y"}, {zRES,"3,Y"},   {zRES,"a=3,Y"},
	{zRES,"b=4,Y"}, {zRES,"c=4,Y"}, {zRES,"d=4,Y"}, {zRES,"e=4,Y"},
	{zRES,"h=4,Y"}, {zRES,"l=4,Y"}, {zRES,"4,Y"},   {zRES,"a=4,Y"},
	{zRES,"b=5,Y"}, {zRES,"c=5,Y"}, {zRES,"d=5,Y"}, {zRES,"e=5,Y"},
	{zRES,"h=5,Y"}, {zRES,"l=5,Y"}, {zRES,"5,Y"},   {zRES,"a=5,Y"},
	{zRES,"b=6,Y"}, {zRES,"c=6,Y"}, {zRES,"d=6,Y"}, {zRES,"e=6,Y"},
	{zRES,"h=6,Y"}, {zRES,"l=6,Y"}, {zRES,"6,Y"},   {zRES,"a=6,Y"},
	{zRES,"b=7,Y"}, {zRES,"c=7,Y"}, {zRES,"d=7,Y"}, {zRES,"e=7,Y"},
	{zRES,"h=7,Y"}, {zRES,"l=7,Y"}, {zRES,"7,Y"},   {zRES,"a=7,Y"},
	{zSET,"b=0,Y"}, {zSET,"c=0,Y"}, {zSET,"d=0,Y"}, {zSET,"e=0,Y"},
	{zSET,"h=0,Y"}, {zSET,"l=0,Y"}, {zSET,"0,Y"},   {zSET,"a=0,Y"},
	{zSET,"b=1,Y"}, {zSET,"c=1,Y"}, {zSET,"d=1,Y"}, {zSET,"e=1,Y"},
	{zSET,"h=1,Y"}, {zSET,"l=1,Y"}, {zSET,"1,Y"},   {zSET,"a=1,Y"},
	{zSET,"b=2,Y"}, {zSET,"c=2,Y"}, {zSET,"d=2,Y"}, {zSET,"e=2,Y"},
	{zSET,"h=2,Y"}, {zSET,"l=2,Y"}, {zSET,"2,Y"},   {zSET,"a=2,Y"},
	{zSET,"b=3,Y"}, {zSET,"c=3,Y"}, {zSET,"d=3,Y"}, {zSET,"e=3,Y"},
	{zSET,"h=3,Y"}, {zSET,"l=3,Y"}, {zSET,"3,Y"},   {zSET,"a=3,Y"},
	{zSET,"b=4,Y"}, {zSET,"c=4,Y"}, {zSET,"d=4,Y"}, {zSET,"e=4,Y"},
	{zSET,"h=4,Y"}, {zSET,"l=4,Y"}, {zSET,"4,Y"},   {zSET,"a=4,Y"},
	{zSET,"b=5,Y"}, {zSET,"c=5,Y"}, {zSET,"d=5,Y"}, {zSET,"e=5,Y"},
	{zSET,"h=5,Y"}, {zSET,"l=5,Y"}, {zSET,"5,Y"},   {zSET,"a=5,Y"},
	{zSET,"b=6,Y"}, {zSET,"c=6,Y"}, {zSET,"d=6,Y"}, {zSET,"e=6,Y"},
	{zSET,"h=6,Y"}, {zSET,"l=6,Y"}, {zSET,"6,Y"},   {zSET,"a=6,Y"},
	{zSET,"b=7,Y"}, {zSET,"c=7,Y"}, {zSET,"d=7,Y"}, {zSET,"e=7,Y"},
	{zSET,"h=7,Y"}, {zSET,"l=7,Y"}, {zSET,"7,Y"},   {zSET,"a=7,Y"}
};

const z180_disassembler::z80dasm z180_disassembler::mnemonic_cb[256] = {
	{zRLC,"b"},     {zRLC,"c"},     {zRLC,"d"},     {zRLC,"e"},
	{zRLC,"h"},     {zRLC,"l"},     {zRLC,"(hl)"},  {zRLC,"a"},
	{zRRC,"b"},     {zRRC,"c"},     {zRRC,"d"},     {zRRC,"e"},
	{zRRC,"h"},     {zRRC,"l"},     {zRRC,"(hl)"},  {zRRC,"a"},
	{zRL,"b"},      {zRL,"c"},      {zRL,"d"},      {zRL,"e"},
	{zRL,"h"},      {zRL,"l"},      {zRL,"(hl)"},   {zRL,"a"},
	{zRR,"b"},      {zRR,"c"},      {zRR,"d"},      {zRR,"e"},
	{zRR,"h"},      {zRR,"l"},      {zRR,"(hl)"},   {zRR,"a"},
	{zSLA,"b"},     {zSLA,"c"},     {zSLA,"d"},     {zSLA,"e"},
	{zSLA,"h"},     {zSLA,"l"},     {zSLA,"(hl)"},  {zSLA,"a"},
	{zSRA,"b"},     {zSRA,"c"},     {zSRA,"d"},     {zSRA,"e"},
	{zSRA,"h"},     {zSRA,"l"},     {zSRA,"(hl)"},  {zSRA,"a"},
	{zSLL,"b"},     {zSLL,"c"},     {zSLL,"d"},     {zSLL,"e"},
	{zSLL,"h"},     {zSLL,"l"},     {zSLL,"(hl)"},  {zSLL,"a"},
	{zSRL,"b"},     {zSRL,"c"},     {zSRL,"d"},     {zSRL,"e"},
	{zSRL,"h"},     {zSRL,"l"},     {zSRL,"(hl)"},  {zSRL,"a"},
	{zBIT,"0,b"},   {zBIT,"0,c"},   {zBIT,"0,d"},   {zBIT,"0,e"},
	{zBIT,"0,h"},   {zBIT,"0,l"},   {zBIT,"0,(hl)"},{zBIT,"0,a"},
	{zBIT,"1,b"},   {zBIT,"1,c"},   {zBIT,"1,d"},   {zBIT,"1,e"},
	{zBIT,"1,h"},   {zBIT,"1,l"},   {zBIT,"1,(hl)"},{zBIT,"1,a"},
	{zBIT,"2,b"},   {zBIT,"2,c"},   {zBIT,"2,d"},   {zBIT,"2,e"},
	{zBIT,"2,h"},   {zBIT,"2,l"},   {zBIT,"2,(hl)"},{zBIT,"2,a"},
	{zBIT,"3,b"},   {zBIT,"3,c"},   {zBIT,"3,d"},   {zBIT,"3,e"},
	{zBIT,"3,h"},   {zBIT,"3,l"},   {zBIT,"3,(hl)"},{zBIT,"3,a"},
	{zBIT,"4,b"},   {zBIT,"4,c"},   {zBIT,"4,d"},   {zBIT,"4,e"},
	{zBIT,"4,h"},   {zBIT,"4,l"},   {zBIT,"4,(hl)"},{zBIT,"4,a"},
	{zBIT,"5,b"},   {zBIT,"5,c"},   {zBIT,"5,d"},   {zBIT,"5,e"},
	{zBIT,"5,h"},   {zBIT,"5,l"},   {zBIT,"5,(hl)"},{zBIT,"5,a"},
	{zBIT,"6,b"},   {zBIT,"6,c"},   {zBIT,"6,d"},   {zBIT,"6,e"},
	{zBIT,"6,h"},   {zBIT,"6,l"},   {zBIT,"6,(hl)"},{zBIT,"6,a"},
	{zBIT,"7,b"},   {zBIT,"7,c"},   {zBIT,"7,d"},   {zBIT,"7,e"},
	{zBIT,"7,h"},   {zBIT,"7,l"},   {zBIT,"7,(hl)"},{zBIT,"7,a"},
	{zRES,"0,b"},   {zRES,"0,c"},   {zRES,"0,d"},   {zRES,"0,e"},
	{zRES,"0,h"},   {zRES,"0,l"},   {zRES,"0,(hl)"},{zRES,"0,a"},
	{zRES,"1,b"},   {zRES,"1,c"},   {zRES,"1,d"},   {zRES,"1,e"},
	{zRES,"1,h"},   {zRES,"1,l"},   {zRES,"1,(hl)"},{zRES,"1,a"},
	{zRES,"2,b"},   {zRES,"2,c"},   {zRES,"2,d"},   {zRES,"2,e"},
	{zRES,"2,h"},   {zRES,"2,l"},   {zRES,"2,(hl)"},{zRES,"2,a"},
	{zRES,"3,b"},   {zRES,"3,c"},   {zRES,"3,d"},   {zRES,"3,e"},
	{zRES,"3,h"},   {zRES,"3,l"},   {zRES,"3,(hl)"},{zRES,"3,a"},
	{zRES,"4,b"},   {zRES,"4,c"},   {zRES,"4,d"},   {zRES,"4,e"},
	{zRES,"4,h"},   {zRES,"4,l"},   {zRES,"4,(hl)"},{zRES,"4,a"},
	{zRES,"5,b"},   {zRES,"5,c"},   {zRES,"5,d"},   {zRES,"5,e"},
	{zRES,"5,h"},   {zRES,"5,l"},   {zRES,"5,(hl)"},{zRES,"5,a"},
	{zRES,"6,b"},   {zRES,"6,c"},   {zRES,"6,d"},   {zRES,"6,e"},
	{zRES,"6,h"},   {zRES,"6,l"},   {zRES,"6,(hl)"},{zRES,"6,a"},
	{zRES,"7,b"},   {zRES,"7,c"},   {zRES,"7,d"},   {zRES,"7,e"},
	{zRES,"7,h"},   {zRES,"7,l"},   {zRES,"7,(hl)"},{zRES,"7,a"},
	{zSET,"0,b"},   {zSET,"0,c"},   {zSET,"0,d"},   {zSET,"0,e"},
	{zSET,"0,h"},   {zSET,"0,l"},   {zSET,"0,(hl)"},{zSET,"0,a"},
	{zSET,"1,b"},   {zSET,"1,c"},   {zSET,"1,d"},   {zSET,"1,e"},
	{zSET,"1,h"},   {zSET,"1,l"},   {zSET,"1,(hl)"},{zSET,"1,a"},
	{zSET,"2,b"},   {zSET,"2,c"},   {zSET,"2,d"},   {zSET,"2,e"},
	{zSET,"2,h"},   {zSET,"2,l"},   {zSET,"2,(hl)"},{zSET,"2,a"},
	{zSET,"3,b"},   {zSET,"3,c"},   {zSET,"3,d"},   {zSET,"3,e"},
	{zSET,"3,h"},   {zSET,"3,l"},   {zSET,"3,(hl)"},{zSET,"3,a"},
	{zSET,"4,b"},   {zSET,"4,c"},   {zSET,"4,d"},   {zSET,"4,e"},
	{zSET,"4,h"},   {zSET,"4,l"},   {zSET,"4,(hl)"},{zSET,"4,a"},
	{zSET,"5,b"},   {zSET,"5,c"},   {zSET,"5,d"},   {zSET,"5,e"},
	{zSET,"5,h"},   {zSET,"5,l"},   {zSET,"5,(hl)"},{zSET,"5,a"},
	{zSET,"6,b"},   {zSET,"6,c"},   {zSET,"6,d"},   {zSET,"6,e"},
	{zSET,"6,h"},   {zSET,"6,l"},   {zSET,"6,(hl)"},{zSET,"6,a"},
	{zSET,"7,b"},   {zSET,"7,c"},   {zSET,"7,d"},   {zSET,"7,e"},
	{zSET,"7,h"},   {zSET,"7,l"},   {zSET,"7,(hl)"},{zSET,"7,a"}
};

const z180_disassembler::z80dasm z180_disassembler::mnemonic_ed[256]= {
	{zIN0,"b,(B)"}, {zOUT0,"(B),b"},{zDB,"?"},      {zDB,"?"},
	{zTST,"b"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"c,(B)"}, {zOUT0,"(B),c"},{zDB,"?"},      {zDB,"?"},
	{zTST,"c"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"d,(B)"}, {zOUT0,"(B),d"},{zDB,"?"},      {zDB,"?"},
	{zTST,"d"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"e,(B)"}, {zOUT0,"(B),e"},{zDB,"?"},      {zDB,"?"},
	{zTST,"e"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"h,(B)"}, {zOUT0,"(B),h"},{zDB,"?"},      {zDB,"?"},
	{zTST,"h"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"l,(B)"}, {zOUT0,"(B),l"},{zDB,"?"},      {zDB,"?"},
	{zTST,"l"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"f,(B)"}, {zOUT0,"(B),0"},{zDB,"?"},      {zDB,"?"},
	{zTST,"(hl)"},  {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN0,"a,(B)"}, {zOUT0,"(B),a"},{zDB,"?"},      {zDB,"?"},
	{zTST,"a"},     {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zIN,"b,(c)"},  {zOUT,"(c),b"}, {zSBC,"hl,bc"}, {zLD,"(W),bc"},
	{zNEG,nullptr},       {zRETN,nullptr},      {zIM,"0"},      {zLD,"i,a"},
	{zIN,"c,(c)"},  {zOUT,"(c),c"}, {zADC,"hl,bc"}, {zLD,"bc,(W)"},
	{zMLT,"bc"},    {zRETI,nullptr},      {zIM,"0"},      {zLD,"r,a"},
	{zIN,"d,(c)"},  {zOUT,"(c),d"}, {zSBC,"hl,de"}, {zLD,"(W),de"},
	{zNEG,"*"},     {zRETN,nullptr},      {zIM,"1"},      {zLD,"a,i"},
	{zIN,"e,(c)"},  {zOUT,"(c),e"}, {zADC,"hl,de"}, {zLD,"de,(W)"},
	{zMLT,"de"},    {zRETI,nullptr},      {zIM,"2"},      {zLD,"a,r"},
	{zIN,"h,(c)"},  {zOUT,"(c),h"}, {zSBC,"hl,hl"}, {zLD,"(W),hl"},
	{zTST,"B"},     {zRETN,nullptr},      {zIM,"0"},      {zRRD,"(hl)"},
	{zIN,"l,(c)"},  {zOUT,"(c),l"}, {zADC,"hl,hl"}, {zLD,"hl,(W)"},
	{zMLT,"hl"},    {zRETI,nullptr},      {zIM,"0"},      {zRLD,"(hl)"},
	{zIN,"0,(c)"},  {zOUT,"(c),0"}, {zSBC,"hl,sp"}, {zLD,"(W),sp"},
	{zTSTIO,"B"},   {zRETN,nullptr},      {zSLP,nullptr},       {zDB,"?"},
	{zIN,"a,(c)"},  {zOUT,"(c),a"}, {zADC,"hl,sp"}, {zLD,"sp,(W)"},
	{zMLT,"sp"},    {zRETI,nullptr},      {zIM,"2"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTIM,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTDM,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTIMR,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zOTDMR,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLDI,nullptr},       {zCPI,nullptr},       {zINI,nullptr},       {zOUTI,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLDD,nullptr},       {zCPD,nullptr},       {zIND,nullptr},       {zOUTD,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLDIR,nullptr},      {zCPIR,nullptr},      {zINIR,nullptr},      {zOTIR,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLDDR,nullptr},      {zCPDR,nullptr},      {zINDR,nullptr},      {zOTDR,nullptr},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"}
};

const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx[256]= {
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zADD,"I,bc"},  {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zADD,"I,de"},  {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zLD,"I,N"},    {zLD,"(W),I"},  {zINC,"I"},
	{zINC,"Ih"},    {zDEC,"Ih"},    {zLD,"Ih,B"},   {zDB,"?"},
	{zDB,"?"},      {zADD,"I,I"},   {zLD,"I,(W)"},  {zDEC,"I"},
	{zINC,"Il"},    {zDEC,"Il"},    {zLD,"Il,B"},   {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zINC,"X"},     {zDEC,"X"},     {zLD,"X,B"},    {zDB,"?"},
	{zDB,"?"},      {zADD,"I,sp"},  {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLD,"b,Ih"},   {zLD,"b,Il"},   {zLD,"b,X"},    {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLD,"c,Ih"},   {zLD,"c,Il"},   {zLD,"c,X"},    {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLD,"d,Ih"},   {zLD,"d,Il"},   {zLD,"d,X"},    {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLD,"e,Ih"},   {zLD,"e,Il"},   {zLD,"e,X"},    {zDB,"?"},
	{zLD,"Ih,b"},   {zLD,"Ih,c"},   {zLD,"Ih,d"},   {zLD,"Ih,e"},
	{zLD,"Ih,Ih"},  {zLD,"Ih,Il"},  {zLD,"h,X"},    {zLD,"Ih,a"},
	{zLD,"Il,b"},   {zLD,"Il,c"},   {zLD,"Il,d"},   {zLD,"Il,e"},
	{zLD,"Il,Ih"},  {zLD,"Il,Il"},  {zLD,"l,X"},    {zLD,"Il,a"},
	{zLD,"X,b"},    {zLD,"X,c"},    {zLD,"X,d"},    {zLD,"X,e"},
	{zLD,"X,h"},    {zLD,"X,l"},    {zDB,"?"},      {zLD,"X,a"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zLD,"a,Ih"},   {zLD,"a,Il"},   {zLD,"a,X"},    {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zADD,"a,Ih"},  {zADD,"a,Il"},  {zADD,"a,X"},   {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zADC,"a,Ih"},  {zADC,"a,Il"},  {zADC,"a,X"},   {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zSUB,"Ih"},    {zSUB,"Il"},    {zSUB,"X"},     {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zSBC,"a,Ih"},  {zSBC,"a,Il"},  {zSBC,"a,X"},   {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zAND,"Ih"},    {zAND,"Il"},    {zAND,"X"},     {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zXOR,"Ih"},    {zXOR,"Il"},    {zXOR,"X"},     {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zOR,"Ih"},     {zOR,"Il"},     {zOR,"X"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zCP,"Ih"},     {zCP,"Il"},     {zCP,"X"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"cb"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zPOP,"I"},     {zDB,"?"},      {zEX,"(sp),I"},
	{zDB,"?"},      {zPUSH,"I"},    {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zJP,"(I)"},    {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zLD,"sp,I"},   {zDB,"?"},      {zDB,"?"},
	{zDB,"?"},      {zDB,"?"},      {zDB,"?"},      {zDB,"?"}
};

const z180_disassembler::z80dasm z180_disassembler::mnemonic_main[256]= {
	{zNOP,nullptr},       {zLD,"bc,N"},   {zLD,"(bc),a"}, {zINC,"bc"},
	{zINC,"b"},     {zDEC,"b"},     {zLD,"b,B"},    {zRLCA,nullptr},
	{zEX,"af,af'"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"},
	{zINC,"c"},     {zDEC,"c"},     {zLD,"c,B"},    {zRRCA,nullptr},
	{zDJNZ,"O"},    {zLD,"de,N"},   {zLD,"(de),a"}, {zINC,"de"},
	{zINC,"d"},     {zDEC,"d"},     {zLD,"d,B"},    {zRLA,nullptr},
	{zJR,"O"},      {zADD,"hl,de"}, {zLD,"a,(de)"}, {zDEC,"de"},
	{zINC,"e"},     {zDEC,"e"},     {zLD,"e,B"},    {zRRA,nullptr},
	{zJR,"nz,O"},   {zLD,"hl,N"},   {zLD,"(W),hl"}, {zINC,"hl"},
	{zINC,"h"},     {zDEC,"h"},     {zLD,"h,B"},    {zDAA,nullptr},
	{zJR,"z,O"},    {zADD,"hl,hl"}, {zLD,"hl,(W)"}, {zDEC,"hl"},
	{zINC,"l"},     {zDEC,"l"},     {zLD,"l,B"},    {zCPL,nullptr},
	{zJR,"nc,O"},   {zLD,"sp,N"},   {zLD,"(W),a"},  {zINC,"sp"},
	{zINC,"(hl)"},  {zDEC,"(hl)"},  {zLD,"(hl),B"}, {zSCF,nullptr},
	{zJR,"c,O"},    {zADD,"hl,sp"}, {zLD,"a,(W)"},  {zDEC,"sp"},
	{zINC,"a"},     {zDEC,"a"},     {zLD,"a,B"},    {zCCF,nullptr},
	{zLD,"b,b"},    {zLD,"b,c"},    {zLD,"b,d"},    {zLD,"b,e"},
	{zLD,"b,h"},    {zLD,"b,l"},    {zLD,"b,(hl)"}, {zLD,"b,a"},
	{zLD,"c,b"},    {zLD,"c,c"},    {zLD,"c,d"},    {zLD,"c,e"},
	{zLD,"c,h"},    {zLD,"c,l"},    {zLD,"c,(hl)"}, {zLD,"c,a"},
	{zLD,"d,b"},    {zLD,"d,c"},    {zLD,"d,d"},    {zLD,"d,e"},
	{zLD,"d,h"},    {zLD,"d,l"},    {zLD,"d,(hl)"}, {zLD,"d,a"},
	{zLD,"e,b"},    {zLD,"e,c"},    {zLD,"e,d"},    {zLD,"e,e"},
	{zLD,"e,h"},    {zLD,"e,l"},    {zLD,"e,(hl)"}, {zLD,"e,a"},
	{zLD,"h,b"},    {zLD,"h,c"},    {zLD,"h,d"},    {zLD,"h,e"},
	{zLD,"h,h"},    {zLD,"h,l"},    {zLD,"h,(hl)"}, {zLD,"h,a"},
	{zLD,"l,b"},    {zLD,"l,c"},    {zLD,"l,d"},    {zLD,"l,e"},
	{zLD,"l,h"},    {zLD,"l,l"},    {zLD,"l,(hl)"}, {zLD,"l,a"},
	{zLD,"(hl),b"}, {zLD,"(hl),c"}, {zLD,"(hl),d"}, {zLD,"(hl),e"},
	{zLD,"(hl),h"}, {zLD,"(hl),l"}, {zHLT,nullptr},       {zLD,"(hl),a"},
	{zLD,"a,b"},    {zLD,"a,c"},    {zLD,"a,d"},    {zLD,"a,e"},
	{zLD,"a,h"},    {zLD,"a,l"},    {zLD,"a,(hl)"}, {zLD,"a,a"},
	{zADD,"a,b"},   {zADD,"a,c"},   {zADD,"a,d"},   {zADD,"a,e"},
	{zADD,"a,h"},   {zADD,"a,l"},   {zADD,"a,(hl)"},{zADD,"a,a"},
	{zADC,"a,b"},   {zADC,"a,c"},   {zADC,"a,d"},   {zADC,"a,e"},
	{zADC,"a,h"},   {zADC,"a,l"},   {zADC,"a,(hl)"},{zADC,"a,a"},
	{zSUB,"b"},     {zSUB,"c"},     {zSUB,"d"},     {zSUB,"e"},
	{zSUB,"h"},     {zSUB,"l"},     {zSUB,"(hl)"},  {zSUB,"a"},
	{zSBC,"a,b"},   {zSBC,"a,c"},   {zSBC,"a,d"},   {zSBC,"a,e"},
	{zSBC,"a,h"},   {zSBC,"a,l"},   {zSBC,"a,(hl)"},{zSBC,"a,a"},
	{zAND,"b"},     {zAND,"c"},     {zAND,"d"},     {zAND,"e"},
	{zAND,"h"},     {zAND,"l"},     {zAND,"(hl)"},  {zAND,"a"},
	{zXOR,"b"},     {zXOR,"c"},     {zXOR,"d"},     {zXOR,"e"},
	{zXOR,"h"},     {zXOR,"l"},     {zXOR,"(hl)"},  {zXOR,"a"},
	{zOR,"b"},      {zOR,"c"},      {zOR,"d"},      {zOR,"e"},
	{zOR,"h"},      {zOR,"l"},      {zOR,"(hl)"},   {zOR,"a"},
	{zCP,"b"},      {zCP,"c"},      {zCP,"d"},      {zCP,"e"},
	{zCP,"h"},      {zCP,"l"},      {zCP,"(hl)"},   {zCP,"a"},
	{zRET,"nz"},    {zPOP,"bc"},    {zJP,"nz,A"},   {zJP,"A"},
	{zCALL,"nz,A"}, {zPUSH,"bc"},   {zADD,"a,B"},   {zRST,"V"},
	{zRET,"z"},     {zRET,nullptr},       {zJP,"z,A"},    {zDB,"cb"},
	{zCALL,"z,A"},  {zCALL,"A"},    {zADC,"a,B"},   {zRST,"V"},
	{zRET,"nc"},    {zPOP,"de"},    {zJP,"nc,A"},   {zOUT,"(P),a"},
	{zCALL,"nc,A"}, {zPUSH,"de"},   {zSUB,"B"},     {zRST,"V"},
	{zRET,"c"},     {zEXX,nullptr},       {zJP,"c,A"},    {zIN,"a,(P)"},
	{zCALL,"c,A"},  {zDB,"dd"},     {zSBC,"a,B"},   {zRST,"V"},
	{zRET,"po"},    {zPOP,"hl"},    {zJP,"po,A"},   {zEX,"(sp),hl"},
	{zCALL,"po,A"}, {zPUSH,"hl"},   {zAND,"B"},     {zRST,"V"},
	{zRET,"pe"},    {zJP,"(hl)"},   {zJP,"pe,A"},   {zEX,"de,hl"},
	{zCALL,"pe,A"}, {zDB,"ed"},     {zXOR,"B"},     {zRST,"V"},
	{zRET,"p"},     {zPOP,"af"},    {zJP,"p,A"},    {zDI,nullptr},
	{zCALL,"p,A"},  {zPUSH,"af"},   {zOR,"B"},      {zRST,"V"},
	{zRET,"m"},     {zLD,"sp,hl"},  {zJP,"m,A"},    {zEI,nullptr},
	{zCALL,"m,A"},  {zDB,"fd"},     {zCP,"B"},      {zRST,"V"}
};

char z180_disassembler::sign(int8_t offset)
{
	return (offset < 0)? '-':'+';
}

int z180_disassembler::offs(int8_t offset)
{
	if (offset < 0) return -offset;
	return offset;
}

/****************************************************************************
 * Disassemble opcode at PC and return number of bytes it takes
 ****************************************************************************/
offs_t z180_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
	const z80dasm *d;
	const char *src, *ixy;
	int8_t offset = 0;
	uint8_t op, op1 = 0;
	uint16_t ea;
	offs_t pos = pc;
	uint32_t flags = 0;

	ixy = "oops!!";

	op = opcodes.r8(pos++);

	switch (op)
	{
	case 0xcb:
		op = opcodes.r8(pos++);
		d = &mnemonic_cb[op];
		break;
	case 0xed:
		op1 = opcodes.r8(pos++);
		d = &mnemonic_ed[op1];
		break;
	case 0xdd:
		ixy = "ix";
		op1 = opcodes.r8(pos++);
		if( op1 == 0xcb )
		{
			offset = (int8_t) params.r8(pos++);
			op1 = opcodes.r8(pos++); // M1 fetch, unlike Z80
			d = &mnemonic_xx_cb[op1];
		}
		else d = &mnemonic_xx[op1];
		break;
	case 0xfd:
		ixy = "iy";
		op1 = opcodes.r8(pos++);
		if( op1 == 0xcb )
		{
			offset = (int8_t) params.r8(pos++);
			op1 = opcodes.r8(pos++); // M1 fetch, unlike Z80
			d = &mnemonic_xx_cb[op1];
		}
		else d = &mnemonic_xx[op1];
		break;
	default:
		d = &mnemonic_main[op];
		break;
	}

	bool comma = false;
	if( d->arguments )
	{
		util::stream_format(stream, "%-5s ", s_mnemonic[d->mnemonic]);
		src = d->arguments;
		while( *src )
		{
			switch( *src )
			{
			case '?':   /* illegal opcode */
				util::stream_format(stream, "$%02x,$%02x", op, op1);
				break;
			case 'A':
				ea = params.r16(pos);
				pos += 2;
				util::stream_format(stream, "$%04X", ea);
				break;
			case 'B':   /* Byte op arg */
				ea = params.r8(pos++);
				util::stream_format(stream, "$%02X", ea);
				break;
			case 'N':   /* Immediate 16 bit */
				ea = params.r16(pos);
				pos += 2;
				util::stream_format(stream, "$%04X", ea);
				break;
			case 'O':   /* Offset relative to PC */
				offset = (int8_t) params.r8(pos++);
				util::stream_format(stream, "$%04X", (pc + offset + 2) & 0xffff);
				break;
			case 'P':   /* Port number */
				ea = params.r8(pos++);
				util::stream_format(stream, "$%02X", ea);
				break;
			case 'V':   /* Restart vector */
				ea = op & 0x38;
				util::stream_format(stream, "$%02X", ea);
				break;
			case 'W':   /* Memory address word */
				ea = params.r16(pos);
				pos += 2;
				util::stream_format(stream, "$%04X", ea);
				break;
			case 'X':
				offset = (int8_t) params.r8(pos++);
				[[fallthrough]];
			case 'Y':
				util::stream_format(stream,"(%s%c$%02x)", ixy, sign(offset), offs(offset));
				break;
			case 'I':
				util::stream_format(stream, "%s", ixy);
				break;
			case ',':
				comma = true;
				[[fallthrough]];
			default:
				stream << *src;
			}
			src++;
		}
	}
	else
	{
		util::stream_format(stream, "%s", s_mnemonic[d->mnemonic]);
	}

	if (d->mnemonic == zCALL || d->mnemonic == zHLT || d->mnemonic == zRST)
		flags = STEP_OVER;
	else if (d->mnemonic == zRETN || d->mnemonic == zRET || d->mnemonic == zRETI)
		flags = STEP_OUT;
	if (d->mnemonic == zCPDR  || d->mnemonic == zCPIR || d->mnemonic == zDJNZ  || d->mnemonic == zINDR ||
		d->mnemonic == zINIR  || d->mnemonic == zLDDR || d->mnemonic == zLDIR  || d->mnemonic == zOTDR ||
		d->mnemonic == zOTDMR || d->mnemonic == zOTIR || d->mnemonic == zOTIMR ||
		((d->mnemonic == zCALL || d->mnemonic == zJP || d->mnemonic == zJR) && comma) ||
		(d->mnemonic == zRET && d->arguments))
		flags = STEP_COND;

	return (pos - pc) | flags | SUPPORTED;
}

u32 z180_disassembler::opcode_alignment() const
{
	return 1;
}