aboutsummaryrefslogtreecommitdiffstats
path: root/tools/z80dis.c
blob: c734d1f34038e77d7c7ac69773a785f5a34bb325 (plain)
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
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

unsigned int Counter;

char *Mnemonics[256] =
{
  "NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA",
  "EX AF,AF'","ADD HL,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA",
  "DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA",
  "JR @h","ADD HL,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA",
  "JR NZ,@h","LD HL,#h","LD (#h),HL","INC HL","INC H","DEC H","LD H,*h","DAA",
  "JR Z,@h","ADD HL,HL","LD HL,(#h)","DEC HL","INC L","DEC L","LD L,*h","CPL",
  "JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (HL)","DEC (HL)","LD (HL),*h","SCF",
  "JR C,@h","ADD HL,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF",
  "LD B,B","LD B,C","LD B,D","LD B,E","LD B,H","LD B,L","LD B,(HL)","LD B,A",
  "LD C,B","LD C,C","LD C,D","LD C,E","LD C,H","LD C,L","LD C,(HL)","LD C,A",
  "LD D,B","LD D,C","LD D,D","LD D,E","LD D,H","LD D,L","LD D,(HL)","LD D,A",
  "LD E,B","LD E,C","LD E,D","LD E,E","LD E,H","LD E,L","LD E,(HL)","LD E,A",
  "LD H,B","LD H,C","LD H,D","LD H,E","LD H,H","LD H,L","LD H,(HL)","LD H,A",
  "LD L,B","LD L,C","LD L,D","LD L,E","LD L,H","LD L,L","LD L,(HL)","LD L,A",
  "LD (HL),B","LD (HL),C","LD (HL),D","LD (HL),E","LD (HL),H","LD (HL),L","HALT","LD (HL),A",
  "LD A,B","LD A,C","LD A,D","LD A,E","LD A,H","LD A,L","LD A,(HL)","LD A,A",
  "ADD B","ADD C","ADD D","ADD E","ADD H","ADD L","ADD (HL)","ADD A",
  "ADC B","ADC C","ADC D","ADC E","ADC H","ADC L","ADC (HL)","ADC,A",
  "SUB B","SUB C","SUB D","SUB E","SUB H","SUB L","SUB (HL)","SUB A",
  "SBC B","SBC C","SBC D","SBC E","SBC H","SBC L","SBC (HL)","SBC A",
  "AND B","AND C","AND D","AND E","AND H","AND L","AND (HL)","AND A",
  "XOR B","XOR C","XOR D","XOR E","XOR H","XOR L","XOR (HL)","XOR A",
  "OR B","OR C","OR D","OR E","OR H","OR L","OR (HL)","OR A",
  "CP B","CP C","CP D","CP E","CP H","CP L","CP (HL)","CP A",
  "RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h",
  "RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h",
  "RET NC","POP DE","JP NC,#h","OUT (*h),A","CALL NC,#h","PUSH DE","SUB *h","RST 10h",
  "RET C","EXX","JP C,#h","IN A,(*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h",
  "RET PO","POP HL","JP PO,#h","EX HL,(SP)","CALL PO,#h","PUSH HL","AND *h","RST 20h",
  "RET PE","JP (HL)","JP PE,#h","EX DE,HL","CALL PE,#h","PFX_ED","XOR *h","RST 28h",
  "RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h",
  "RET M","LD SP,HL","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h"
};

char *MnemonicsCB[256] =
{
  "RLC B","RLC C","RLC D","RLC E","RLC H","RLC L","RLC (HL)","RLC A",
  "RRC B","RRC C","RRC D","RRC E","RRC H","RRC L","RRC (HL)","RRC A",
  "RL B","RL C","RL D","RL E","RL H","RL L","RL (HL)","RL A",
  "RR B","RR C","RR D","RR E","RR H","RR L","RR (HL)","RR A",
  "SLA B","SLA C","SLA D","SLA E","SLA H","SLA L","SLA (HL)","SLA A",
  "SRA B","SRA C","SRA D","SRA E","SRA H","SRA L","SRA (HL)","SRA A",
  "SLL B","SLL C","SLL D","SLL E","SLL H","SLL L","SLL (HL)","SLL A",
  "SRL B","SRL C","SRL D","SRL E","SRL H","SRL L","SRL (HL)","SRL A",
  "BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,H","BIT 0,L","BIT 0,(HL)","BIT 0,A",
  "BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,H","BIT 1,L","BIT 1,(HL)","BIT 1,A",
  "BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,H","BIT 2,L","BIT 2,(HL)","BIT 2,A",
  "BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,H","BIT 3,L","BIT 3,(HL)","BIT 3,A",
  "BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,H","BIT 4,L","BIT 4,(HL)","BIT 4,A",
  "BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,H","BIT 5,L","BIT 5,(HL)","BIT 5,A",
  "BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,H","BIT 6,L","BIT 6,(HL)","BIT 6,A",
  "BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,H","BIT 7,L","BIT 7,(HL)","BIT 7,A",
  "RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,H","RES 0,L","RES 0,(HL)","RES 0,A",
  "RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,H","RES 1,L","RES 1,(HL)","RES 1,A",
  "RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,H","RES 2,L","RES 2,(HL)","RES 2,A",
  "RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,H","RES 3,L","RES 3,(HL)","RES 3,A",
  "RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,H","RES 4,L","RES 4,(HL)","RES 4,A",
  "RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,H","RES 5,L","RES 5,(HL)","RES 5,A",
  "RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,H","RES 6,L","RES 6,(HL)","RES 6,A",
  "RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,H","RES 7,L","RES 7,(HL)","RES 7,A",
  "SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,H","SET 0,L","SET 0,(HL)","SET 0,A",
  "SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,H","SET 1,L","SET 1,(HL)","SET 1,A",
  "SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,H","SET 2,L","SET 2,(HL)","SET 2,A",
  "SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,H","SET 3,L","SET 3,(HL)","SET 3,A",
  "SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,H","SET 4,L","SET 4,(HL)","SET 4,A",
  "SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,H","SET 5,L","SET 5,(HL)","SET 5,A",
  "SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,H","SET 6,L","SET 6,(HL)","SET 6,A",
  "SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,H","SET 7,L","SET 7,(HL)","SET 7,A"
};

char *MnemonicsED[256] =
{
  "??ED00","??ED01","??ED02","??ED03","??ED04","??ED05","??ED06","??ED07",
  "??ED08","??ED09","??ED0A","??ED0B","??ED0C","??ED0D","??ED0E","??ED0F",
  "??ED10","??ED11","??ED12","??ED13","??ED14","??ED15","??ED16","??ED17",
  "??ED18","??ED19","??ED1A","??ED1B","??ED1C","??ED1D","??ED1E","??ED1F",
  "??ED20","??ED21","??ED22","??ED23","??ED24","??ED25","??ED26","??ED27",
  "??ED28","??ED29","??ED2A","??ED2B","??ED2C","??ED2D","??ED2E","??ED2F",
  "??ED30","??ED31","??ED32","??ED33","??ED34","??ED35","??ED36","??ED37",
  "??ED38","??ED39","??ED3A","??ED3B","??ED3C","??ED3D","??ED3E","??ED3F",
  "IN B,(C)","OUT (C),B","SBC HL,BC","LD (#h),BC","NEG","RETN","IM 0","LD I,A",
  "IN C,(C)","OUT (C),C","ADC HL,BC","LD BC,(#h)","??ED4C","RETI","??ED4E","LD R,A",
  "IN D,(C)","OUT (C),D","SBC HL,DE","LD (#h),DE","??ED54","??ED55","IM 1","LD A,I",
  "IN E,(C)","OUT (C),E","ADC HL,DE","LD DE,(#h)","??ED5C","??ED5D","IM 2","LD A,R",
  "IN H,(C)","OUT (C),H","SBC HL,HL","LD (#h),HL","??ED64","??ED65","??ED66","RRD",
  "IN L,(C)","OUT (C),L","ADC HL,HL","LD HL,(#h)","??ED6C","??ED6D","??ED6E","RLD",
  "IN F,(C)","??ED71","SBC HL,SP","LD (#h),SP","??ED74","??ED75","??ED76","??ED77",
  "IN A,(C)","OUT (C),A","ADC HL,SP","LD SP,(#h)","??ED7C","??ED7D","??ED7E","??ED7F",
  "??ED80","??ED81","??ED82","??ED83","??ED84","??ED85","??ED86","??ED87",
  "??ED88","??ED89","??ED8A","??ED8B","??ED8C","??ED8D","??ED8E","??ED8F",
  "??ED90","??ED91","??ED92","??ED93","??ED94","??ED95","??ED96","??ED97",
  "??ED98","??ED99","??ED9A","??ED9B","??ED9C","??ED9D","??ED9E","??ED9F",
  "LDI","CPI","INI","OUTI","??EDA4","??EDA5","??EDA6","??EDA7",
  "LDD","CPD","IND","OUTD","??EDAC","??EDAD","??EDAE","??EDAF",
  "LDIR","CPIR","INIR","OTIR","??EDB4","??EDB5","??EDB6","??EDB7",
  "LDDR","CPDR","INDR","OTDR","??EDBC","??EDBD","??EDBE","??EDBF",
  "??EDC0","??EDC1","??EDC2","??EDC3","??EDC4","??EDC5","??EDC6","??EDC7",
  "??EDC8","??EDC9","??EDCA","??EDCB","??EDCC","??EDCD","??EDCE","??EDCF",
  "??EDD0","??EDD1","??EDD2","??EDD3","??EDD4","??EDD5","??EDD6","??EDD7",
  "??EDD8","??EDD9","??EDDA","??EDDB","??EDDC","??EDDD","??EDDE","??EDDF",
  "??EDE0","??EDE1","??EDE2","??EDE3","??EDE4","??EDE5","??EDE6","??EDE7",
  "??EDE8","??EDE9","??EDEA","??EDEB","??EDEC","??EDED","??EDEE","??EDEF",
  "??EDF0","??EDF1","??EDF2","??EDF3","??EDF4","??EDF5","??EDF6","??EDF7",
  "??EDF8","??EDF9","??EDFA","??EDFB","??EDFC","??EDFD","??EDFE","??EDFF"
};

char *MnemonicsXX[256] =
{
  "NOP","LD BC,#h","LD (BC),A","INC BC","INC B","DEC B","LD B,*h","RLCA",
  "EX AF,AF'","ADD I%,BC","LD A,(BC)","DEC BC","INC C","DEC C","LD C,*h","RRCA",
  "DJNZ @h","LD DE,#h","LD (DE),A","INC DE","INC D","DEC D","LD D,*h","RLA",
  "JR @h","ADD I%,DE","LD A,(DE)","DEC DE","INC E","DEC E","LD E,*h","RRA",
  "JR NZ,@h","LD I%,#h","LD (#h),I%","INC I%","INC I%H","DEC I%H","LD I%Xh,*h","DAA",
  "JR Z,@h","ADD I%,I%","LD I%,(#h)","DEC I%","INC I%L","DEC I%L","LD I%L,*h","CPL",
  "JR NC,@h","LD SP,#h","LD (#h),A","INC SP","INC (I%+h)","DEC (I%+h)","LD (I%+h),*h","SCF",
  "JR C,@h","ADD I%,SP","LD A,(#h)","DEC SP","INC A","DEC A","LD A,*h","CCF",
  "LD B,B","LD B,C","LD B,D","LD B,E","LD B,I%H","LD B,I%L","LD B,(I%+h)","LD B,A",
  "LD C,B","LD C,C","LD C,D","LD C,E","LD C,I%H","LD C,I%L","LD C,(I%+h)","LD C,A",
  "LD D,B","LD D,C","LD D,D","LD D,E","LD D,I%H","LD D,I%L","LD D,(I%+h)","LD D,A",
  "LD E,B","LD E,C","LD E,D","LD E,E","LD E,I%H","LD E,I%L","LD E,(I%+h)","LD E,A",
  "LD I%H,B","LD I%H,C","LD I%H,D","LD I%H,E","LD I%H,I%H","LD I%H,I%L","LD H,(I%+h)","LD I%H,A",
  "LD I%L,B","LD I%L,C","LD I%L,D","LD I%L,E","LD I%L,I%H","LD I%L,I%L","LD L,(I%+h)","LD I%L,A",
  "LD (I%+h),B","LD (I%+h),C","LD (I%+h),D","LD (I%+h),E","LD (I%+h),H","LD (I%+h),L","HALT","LD (I%+h),A",
  "LD A,B","LD A,C","LD A,D","LD A,E","LD A,I%H","LD A,I%L","LD A,(I%+h)","LD A,A",
  "ADD B","ADD C","ADD D","ADD E","ADD I%H","ADD I%L","ADD (I%+h)","ADD A",
  "ADC B","ADC C","ADC D","ADC E","ADC I%H","ADC I%L","ADC (I%+h)","ADC,A",
  "SUB B","SUB C","SUB D","SUB E","SUB I%H","SUB I%L","SUB (I%+h)","SUB A",
  "SBC B","SBC C","SBC D","SBC E","SBC I%H","SBC I%L","SBC (I%+h)","SBC A",
  "AND B","AND C","AND D","AND E","AND I%H","AND I%L","AND (I%+h)","AND A",
  "XOR B","XOR C","XOR D","XOR E","XOR I%H","XOR I%L","XOR (I%+h)","XOR A",
  "OR B","OR C","OR D","OR E","OR I%H","OR I%L","OR (I%+h)","OR A",
  "CP B","CP C","CP D","CP E","CP I%H","CP I%L","CP (I%+h)","CP A",
  "RET NZ","POP BC","JP NZ,#h","JP #h","CALL NZ,#h","PUSH BC","ADD *h","RST 00h",
  "RET Z","RET","JP Z,#h","PFX_CB","CALL Z,#h","CALL #h","ADC *h","RST 08h",
  "RET NC","POP DE","JP NC,#h","OUT (*h),A","CALL NC,#h","PUSH DE","SUB *h","RST 10h",
  "RET C","EXX","JP C,#h","IN A,(*h)","CALL C,#h","PFX_DD","SBC *h","RST 18h",
  "RET PO","POP I%","JP PO,#h","EX I%,(SP)","CALL PO,#h","PUSH I%","AND *h","RST 20h",
  "RET PE","JP (I%)","JP PE,#h","EX DE,I%","CALL PE,#h","PFX_ED","XOR *h","RST 28h",
  "RET P","POP AF","JP P,#h","DI","CALL P,#h","PUSH AF","OR *h","RST 30h",
  "RET M","LD SP,I%","JP M,#h","EI","CALL M,#h","PFX_FD","CP *h","RST 38h"
};

char *MnemonicsXXCB[256] =
{
  "RLC B","RLC C","RLC D","RLC E","RLC I%H","RLC I%L","RLC (I%+h)","RLC A",
  "RRC B","RRC C","RRC D","RRC E","RRC I%H","RRC I%L","RRC (I%+h)","RRC A",
  "RL B","RL C","RL D","RL E","RL I%H","RL I%L","RL (I%+h)","RL A",
  "RR B","RR C","RR D","RR E","RR I%H","RR I%L","RR (I%+h)","RR A",
  "SLA B","SLA C","SLA D","SLA E","SLA I%H","SLA I%L","SLA (I%+h)","SLA A",
  "SRA B","SRA C","SRA D","SRA E","SRA I%H","SRA I%L","SRA (I%+h)","SRA A",
  "SLL B","SLL C","SLL D","SLL E","SLL I%H","SLL I%L","SLL (I%+h)","SLL A",
  "SRL B","SRL C","SRL D","SRL E","SRL I%H","SRL I%L","SRL (I%+h)","SRL A",
  "BIT 0,B","BIT 0,C","BIT 0,D","BIT 0,E","BIT 0,I%H","BIT 0,I%L","BIT 0,(I%+h)","BIT 0,A",
  "BIT 1,B","BIT 1,C","BIT 1,D","BIT 1,E","BIT 1,I%H","BIT 1,I%L","BIT 1,(I%+h)","BIT 1,A",
  "BIT 2,B","BIT 2,C","BIT 2,D","BIT 2,E","BIT 2,I%H","BIT 2,I%L","BIT 2,(I%+h)","BIT 2,A",
  "BIT 3,B","BIT 3,C","BIT 3,D","BIT 3,E","BIT 3,I%H","BIT 3,I%L","BIT 3,(I%+h)","BIT 3,A",
  "BIT 4,B","BIT 4,C","BIT 4,D","BIT 4,E","BIT 4,I%H","BIT 4,I%L","BIT 4,(I%+h)","BIT 4,A",
  "BIT 5,B","BIT 5,C","BIT 5,D","BIT 5,E","BIT 5,I%H","BIT 5,I%L","BIT 5,(I%+h)","BIT 5,A",
  "BIT 6,B","BIT 6,C","BIT 6,D","BIT 6,E","BIT 6,I%H","BIT 6,I%L","BIT 6,(I%+h)","BIT 6,A",
  "BIT 7,B","BIT 7,C","BIT 7,D","BIT 7,E","BIT 7,I%H","BIT 7,I%L","BIT 7,(I%+h)","BIT 7,A",
  "RES 0,B","RES 0,C","RES 0,D","RES 0,E","RES 0,I%H","RES 0,I%L","RES 0,(I%+h)","RES 0,A",
  "RES 1,B","RES 1,C","RES 1,D","RES 1,E","RES 1,I%H","RES 1,I%L","RES 1,(I%+h)","RES 1,A",
  "RES 2,B","RES 2,C","RES 2,D","RES 2,E","RES 2,I%H","RES 2,I%L","RES 2,(I%+h)","RES 2,A",
  "RES 3,B","RES 3,C","RES 3,D","RES 3,E","RES 3,I%H","RES 3,I%L","RES 3,(I%+h)","RES 3,A",
  "RES 4,B","RES 4,C","RES 4,D","RES 4,E","RES 4,I%H","RES 4,I%L","RES 4,(I%+h)","RES 4,A",
  "RES 5,B","RES 5,C","RES 5,D","RES 5,E","RES 5,I%H","RES 5,I%L","RES 5,(I%+h)","RES 5,A",
  "RES 6,B","RES 6,C","RES 6,D","RES 6,E","RES 6,I%H","RES 6,I%L","RES 6,(I%+h)","RES 6,A",
  "RES 7,B","RES 7,C","RES 7,D","RES 7,E","RES 7,I%H","RES 7,I%L","RES 7,(I%+h)","RES 7,A",
  "SET 0,B","SET 0,C","SET 0,D","SET 0,E","SET 0,I%H","SET 0,I%L","SET 0,(I%+h)","SET 0,A",
  "SET 1,B","SET 1,C","SET 1,D","SET 1,E","SET 1,I%H","SET 1,I%L","SET 1,(I%+h)","SET 1,A",
  "SET 2,B","SET 2,C","SET 2,D","SET 2,E","SET 2,I%H","SET 2,I%L","SET 2,(I%+h)","SET 2,A",
  "SET 3,B","SET 3,C","SET 3,D","SET 3,E","SET 3,I%H","SET 3,I%L","SET 3,(I%+h)","SET 3,A",
  "SET 4,B","SET 4,C","SET 4,D","SET 4,E","SET 4,I%H","SET 4,I%L","SET 4,(I%+h)","SET 4,A",
  "SET 5,B","SET 5,C","SET 5,D","SET 5,E","SET 5,I%H","SET 5,I%L","SET 5,(I%+h)","SET 5,A",
  "SET 6,B","SET 6,C","SET 6,D","SET 6,E","SET 6,I%H","SET 6,I%L","SET 6,(I%+h)","SET 6,A",
  "SET 7,B","SET 7,C","SET 7,D","SET 7,E","SET 7,I%H","SET 7,I%L","SET 7,(I%+h)","SET 7,A"
};

char *MnemonicsXXED[256] =
{
  "??ED00","??ED01","??ED02","??ED03","??ED04","??ED05","??ED06","??ED07",
  "??ED08","??ED09","??ED0A","??ED0B","??ED0C","??ED0D","??ED0E","??ED0F",
  "??ED10","??ED11","??ED12","??ED13","??ED14","??ED15","??ED16","??ED17",
  "??ED18","??ED19","??ED1A","??ED1B","??ED1C","??ED1D","??ED1E","??ED1F",
  "??ED20","??ED21","??ED22","??ED23","??ED24","??ED25","??ED26","??ED27",
  "??ED28","??ED29","??ED2A","??ED2B","??ED2C","??ED2D","??ED2E","??ED2F",
  "??ED30","??ED31","??ED32","??ED33","??ED34","??ED35","??ED36","??ED37",
  "??ED38","??ED39","??ED3A","??ED3B","??ED3C","??ED3D","??ED3E","??ED3F",
  "IN B,(C)","OUT (C),B","SBC I%,BC","LD (#h),BC","NEG","RETN","IM 0","LD I,A",
  "IN C,(C)","OUT (C),C","ADC I%,BC","LD BC,(#h)","??ED4C","RETI","??ED4E","LD R,A",
  "IN D,(C)","OUT (C),D","SBC I%,DE","LD (#h),DE","??ED54","??ED55","IM 1","LD A,I",
  "IN E,(C)","OUT (C),E","ADC I%,DE","LD DE,(#h)","??ED5C","??ED5D","IM 2","LD A,R",
  "IN I%H,(C)","OUT (C),I%H","SBC I%,I%","LD (#h),I%","??ED64","??ED65","??ED66","RRD",
  "IN I%L,(C)","OUT (C),I%L","ADC I%,I%","LD I%,(#h)","??ED6C","??ED6D","??ED6E","RLD",
  "IN F,(C)","??ED71","SBC I%,SP","LD (#h),SP","??ED74","??ED75","??ED76","??ED77",
  "IN A,(C)","OUT (C),A","ADC I%,SP","LD SP,(#h)","??ED7C","??ED7D","??ED7E","??ED7F",
  "??ED80","??ED81","??ED82","??ED83","??ED84","??ED85","??ED86","??ED87",
  "??ED88","??ED89","??ED8A","??ED8B","??ED8C","??ED8D","??ED8E","??ED8F",
  "??ED90","??ED91","??ED92","??ED93","??ED94","??ED95","??ED96","??ED97",
  "??ED98","??ED99","??ED9A","??ED9B","??ED9C","??ED9D","??ED9E","??ED9F",
  "LDI","CPI","INI","OUTI","??EDA4","??EDA5","??EDA6","??EDA7",
  "LDD","CPD","IND","OUTD","??EDAC","??EDAD","??EDAE","??EDAF",
  "LDIR","CPIR","INIR","OTIR","??EDB4","??EDB5","??EDB6","??EDB7",
  "LDDR","CPDR","INDR","OTDR","??EDBC","??EDBD","??EDBE","??EDBF",
  "??EDC0","??EDC1","??EDC2","??EDC3","??EDC4","??EDC5","??EDC6","??EDC7",
  "??EDC8","??EDC9","??EDCA","??EDCB","??EDCC","??EDCD","??EDCE","??EDCF",
  "??EDD0","??EDD1","??EDD2","??EDD3","??EDD4","??EDD5","??EDD6","??EDD7",
  "??EDD8","??EDD9","??EDDA","??EDDB","??EDDC","??EDDD","??EDDE","??EDDF",
  "??EDE0","??EDE1","??EDE2","??EDE3","??EDE4","??EDE5","??EDE6","??EDE7",
  "??EDE8","??EDE9","??EDEA","??EDEB","??EDEC","??EDED","??EDEE","??EDEF",
  "??EDF0","??EDF1","??EDF2","??EDF3","??EDF4","??EDF5","??EDF6","??EDF7",
  "??EDF8","??EDF9","??EDFA","??EDFB","??EDFC","??EDFD","??EDFE","??EDFF"
};

char **mtable[8] = {
  Mnemonics,
  MnemonicsCB,
  MnemonicsED,
  NULL,
  MnemonicsXX,
  MnemonicsXXCB,
  MnemonicsXXED,
  NULL
};

int DAsm(FILE *);

int DAsm(F)
  FILE *F;
{
  char S[80],T[80],*P,PP,*R;
  int I,J;
  char X[80], *XP;
  unsigned char bytes[8], *bp, *bx;
  int table;
  char XReg;

  XReg = '?';

  bp = bytes;
  if((I=getc(F))<0) return(0);
  printf("%04X:  ",Counter++);
  *bp++ = I;
  
  table = 0;

  *S = 0;
  
  while ( !*S ) {
    switch(I)
      {
      case 0xCB:
	if((I=getc(F))<0) return(0);
	*bp++ = I;
	table = (table & ~3) | 1;
	Counter++;
	break;
      case 0xED:
	if((I=getc(F))<0) return(0);
	*bp++ = I;
	table = (table & ~3) | 2;
	Counter++;
	break;
      case 0xDD:
	if((I=getc(F))<0) return(0);
	*bp++ = I;
	XReg = 'X';
	table |= 4;
	Counter++;
	break;
      case 0xFD:
	if((I=getc(F))<0) return(0);
	*bp++ = I;
	XReg = 'Y';
	table |= 4;
	Counter++;
	break;
      default:
	strcpy(S,mtable[table][I]);
	break;
      }
  }

  P = S;
  R = T;
  while ( (PP = *P++) ) {
    switch ( PP ) {
    case '%':
      *R++ = XReg;
      break;
    case '*':
      if((I=getc(F))<0) return(0);
      *bp++ = I; Counter++;
      R += sprintf(R,"%02X",I);
      break;
    case '#':
      if((I=getc(F))<0) return(0);
      *bp++ = I; Counter++;
      if((J=getc(F))<0) return(0);
      *bp++ = J; Counter++;
      R += sprintf(R,"%04X",256*J+I);
      break;
    case '@':
      if((I=getc(F))<0) return(0);
      *bp++ = I; Counter++;
      if ( I >= 0x80 ) I -= 256;
      R += sprintf(R,"%04X",I+Counter);
      break;
    case '+':
      if((I=getc(F))<0) return(0);
      *bp++ = I; Counter++;
      if ( I >= 0x80 ) {
	PP = '-';
	I = -(I-256);
      }
      R += sprintf(R,"%c%02X",PP,I);
      break;
    default:
      *R++ = PP;
      break;
    }
  }    
  *R = '\0';
       
  XP = X;
  for ( bx = bytes ; bx < bp ; bx++ ) {
    XP += sprintf(XP, "%02X", *bx);
  }
  printf("%-8s ", X);
  XP = X;
  for ( bx = bytes ; bx < bp ; bx++ ) {
    *XP++ = isprint(*bx) ? *bx : '.';
  }
  *XP = '\0';
  printf("%-4s  %s\n", X, T);
  return 1;
}  

int main(argc,argv)
  int argc;
  char *argv[];
{
  FILE *F;  
    
  if(argc < 2) {
    fprintf(stderr, "Usage: %s filename [offset]\n", argv[0]);
    return 1;
  }

  if(!(F=fopen(argv[1],"rb"))) {
    perror(argv[1]);
    return 2;
  }
  
  Counter = (argc > 2) ? strtoul(argv[2], NULL, 0) : 0;
  while(DAsm(F))
    ;
  fclose(F);

  return 0;
}