|
|
1.1 root 1: /*****************************************************************************
2: *
3: * makez80.c
4: * 486++ asm emitter for a Z80 cpu core
5: * supports GNU assembler and NASM
6: *
7: * Copyright (c) 1999 Juergen Buchmueller, all rights reserved.
8: *
9: * - This source code is released as freeware for non-commercial purposes.
10: * - You are free to use and redistribute this code in modified or
11: * unmodified form, provided you list me in the credits.
12: * - If you modify this source code, you must add a notice to each modified
13: * source file that it has been changed. If you're a nice person, you
14: * will clearly mark each change too. :)
15: * - If you wish to use this for commercial purposes, please contact me at
16: * [email protected]
17: * - The author of this copywritten work reserves the right to change the
18: * terms of its usage and license at any time, including retroactively
19: * - This entire notice must remain in the source code.
20: *
21: *****************************************************************************/
22:
23: #include <stdio.h>
24: #include <stdarg.h>
25: #include <string.h>
26: #include <signal.h>
27: #include "cpuintrf.h"
28: #include "osd_cpu.h"
29:
30: #define FAST_MEMORY 1
31: #define INLINE_IOPORTS 0 /* inline cpu_readport/cpu_writeport functions */
32: #define BUSY_LOOP_HACKS 1 /* break out of tight loops waiting for an interrupt */
33: #define WBYTE_EA4_EDX 1 /* use one writeback function for DD/FD CB <ofs8> xx opcodes */
34: #define EARLY_CTC 1
35: #define CALC_PREVPC 0 /* calculate previouspc */
36:
37: #define ABITS 4 /* ABITS2_16 + ABITS_MIN_16 */
38:
39: #define GLOBL 0
40:
41: #define GAS 0
42: #define NASM 1
43: #define TASM 2
44:
45: typedef unsigned char byte;
46: typedef unsigned short word;
47: typedef unsigned long dword;
48:
49: FILE *output;
50: int as = GAS;
51: int verbose = 0, mame_debug = 0, optimize = 0;
52: int opcodes = 0;
53: int rbyte = 0, rword = 0, wbyte = 0, wword = 0;
54: int align_funcs = 2, align_jumps = 2, align_loops = 1;
55:
56: typedef enum {
57: none=0,
58: al, ah, cl, ch, dl, dh, bl, bh,
59: ax, cx, dx, bx, si, di, bp, sp,
60: eax, ecx, edx, ebx, esi, edi, ebp, esp
61: } x86_regs;
62:
63: typedef enum {
64: dm, db, dw, dd, align, extrn, globl, text,
65: data, aaa, aad, aam, aas, adc, adcb, adcl,
66: adcw, add, addb, addl, addw, and, andb, andl,
67: andw, bswap, bt, btc, btr, bts, call, callf,
68: cbw, cdq, clc, cld, cli, clts, cmc, cmp,
69: cmpb, cmpl, cmpsb, cmpsd, cmpsw, cmpw, cpuid, cwd,
70: cwde, daa, das, dec, decb, decl, decw, div,
71: divb, divd, divw, fwait, hlt, idiv, idivb, idivd,
72: idivw, imul, imulb, imuld, imulw, in, inc, incb,
73: incl, incw, insb, insd, insw, intr, into, iret,
74: iretd, ja, jae, jael, jal, jb, jbe, jbel,
75: jbl, jc, jcl, jcxz, je, jecxz, jel, jg,
76: jge, jgel, jgl, jl, jle, jlel, jll, jmp,
77: jmpf, jmpl, jna, jnae, jnael, jnal, jnb, jnbe,
78: jnbel, jnbl, jnc, jncl, jne, jnel, jng, jnge,
79: jngel, jngl, jnl, jnle, jnlel, jnll, jno, jnol,
80: jnp, jnpl, jns, jnsl, jnz, jnzl, jo, jol,
81: jp, jpe, jpel, jpl, jpo, jpol, js, jsl,
82: jz, jzl, lahf, lds, lea, leave, les, lfs,
83: lgdt, lgs, lidt, lldt, lmsw, lock, lodsb, lodsd,
84: lodsw, loop, loope, loopne, loopnz, loopz, lss, ltr,
85: mov, movb, movl, movsb, movsbl, movsbw, movsd, movsw,
86: movswl, movw, movzbl, movzbw, movzwl, mul, mulb, muld,
87: mulw, neg, negb, negw, negl, nop, not, notb,
88: notw, notl, or, orb, orl, orw, out, outsb,
89: outsd, outsw, pop, popa, popad, popl, popf, popfd,
90: popw, push, pusha, pushad, pushl, pushf, pushfd, pushw,
91: rclb, rcll, rclw, rcrb, rcrl, rcrw, rep, repe,
92: repne, repnz, repz, ret, retd, retf, retfd, rolb,
93: roll, rolw, rorb, rorl, rorw, sahf, salb, sall,
94: salw, sarb, sarl, sarw, sbbb, sbbl, sbbw, scasb,
95: scasd, scasw, seta, setae, setb, setbe, setc, sete,
96: setg, setge, setl, setle, setna, setnae, setnb, setnbe,
97: setnc, setne, setng, setnge, setnl, setnle, setno, setnp,
98: setns, setnz, seto, setp, setpe, setpo, sets, setz,
99: sgdt, shlb, shld, shll, shlw, shrb, shrd, shrl,
100: shrw, sidt, sldt, smsw, stc, std, sti, stosb,
101: stosd, stosw, subb, subl, subw, testb, testl, testw,
102: verr, verw, wait, xchg, xchgb, xchgw, xchgl, xlat,
103: xlatb, xorb, xorl, xorw
104: } x86_token;
105:
106: #define AL R(al)
107: #define AH R(ah)
108: #define CL R(cl)
109: #define CH R(ch)
110: #define DL R(dl)
111: #define DH R(dh)
112: #define BL R(bl)
113: #define BH R(bh)
114: #define AX R(ax)
115: #define CX R(cx)
116: #define DX R(dx)
117: #define BX R(bx)
118: #define SI R(si)
119: #define DI R(di)
120: #define BP R(bp)
121: #define EAX R(eax)
122: #define ECX R(ecx)
123: #define EDX R(edx)
124: #define EBX R(ebx)
125: #define ESI R(esi)
126: #define EDI R(edi)
127: #define EBP R(ebp)
128: #define ESP R(esp)
129:
130: void emit(const char *fmt, ...) __attribute__((format(printf,1,2)));
131:
132: void com(const char *fmt, ...);
133:
134: const char *O(const char *symbol);
135:
136: int str(char *dst, const char *src);
137:
138: const char *x86_rstr[][3] = {
139: {"", "", "" },
140: {"%al", "al", "al" },
141: {"%ah", "ah", "ah" },
142: {"%cl", "cl", "cl" },
143: {"%ch", "ch", "ch" },
144: {"%dl", "dl", "dl" },
145: {"%dh", "dh", "dh" },
146: {"%bl", "bl", "bl" },
147: {"%bh", "bh", "bh" },
148: {"%ax", "ax", "ax" },
149: {"%cx", "cx", "cx" },
150: {"%dx", "dx", "dx" },
151: {"%bx", "bx", "bx" },
152: {"%si", "si", "si" },
153: {"%di", "di", "di" },
154: {"%bp", "bp", "bp" },
155: {"%sp", "sp", "sp" },
156: {"%eax","eax","eax" },
157: {"%ecx","ecx","ecx" },
158: {"%edx","edx","edx" },
159: {"%ebx","ebx","ebx" },
160: {"%esi","esi","esi" },
161: {"%edi","edi","edi" },
162: {"%ebp","ebp","ebp" },
163: {"%esp","esp","esp" },
164: };
165:
166: const char *x86_token_str[][3] = {
167: {".ascii", "db", "db", },
168: {".byte", "db", "db", },
169: {".short", "dw", "dw", },
170: {".long", "dd", "dd", },
171: {".align", "align", "align", },
172: {".extern", "extern", "extern", },
173: {".global", "global", "global", },
174: {".text", "section\t.text", ".code", },
175: {".data", "section\t.data", ".data", },
176: {"aaa", "aaa", "aaa", },
177: {"aad", "aad", "aad", },
178: {"aam", "aam", "aam", },
179: {"aas", "aas", "aas", },
180: {"adc", "adc", "adc", },
181: {"adcb", "adc", "adc", },
182: {"adcl", "adc", "adc", },
183: {"adcw", "adc", "adc", },
184: {"add", "add", "add", },
185: {"addb", "add", "add", },
186: {"addl", "add", "add", },
187: {"addw", "add", "add", },
188: {"and", "and", "and", },
189: {"andb", "and", "and", },
190: {"andl", "and", "and", },
191: {"andw", "and", "and", },
192: {"bswap", "bswap", "bswap", },
193: {"bt", "bt", "bt", },
194: {"btc", "btc", "btc", },
195: {"btr", "btr", "btr", },
196: {"bts", "bts", "bts", },
197: {"call", "call", "call", },
198: {"callf", "callf", "callf", },
199: {"cbw", "cbw", "cbw", },
200: {"cdq", "cdq", "cdq", },
201: {"clc", "clc", "clc", },
202: {"cld", "cld", "cld", },
203: {"cli", "cli", "cli", },
204: {"clts", "clts", "clts", },
205: {"cmc", "cmc", "cmc", },
206: {"cmp", "cmp", "cmp", },
207: {"cmpb", "cmp", "cmp", },
208: {"cmpl", "cmp", "cmp", },
209: {"cmpsb", "cmpsb", "cmpsb", },
210: {"cmpsd", "cmpsd", "cmpsd", },
211: {"cmpsw", "cmpsw", "cmpsw", },
212: {"cmpw", "cmp", "cmp", },
213: {"cpuid", "cpuid", "cpuid", },
214: {"cwd", "cwd", "cwd", },
215: {"cwde", "cwde", "cwde", },
216: {"daa", "daa", "daa", },
217: {"das", "das", "das", },
218: {"dec", "dec", "dec", },
219: {"decb", "dec", "dec", },
220: {"decl", "dec", "dec", },
221: {"decw", "dec", "dec", },
222: {"div", "div", "div", },
223: {"divb", "div", "div", },
224: {"divd", "div", "div", },
225: {"divw", "div", "div", },
226: {"fwait", "fwait", "fwait", },
227: {"hlt", "hlt", "hlt", },
228: {"idiv", "idiv", "idiv", },
229: {"idivb", "idiv", "idiv", },
230: {"idivd", "idiv", "idiv", },
231: {"idivw", "idiv", "idiv", },
232: {"imul", "imul", "imul", },
233: {"imulb", "imul", "imul", },
234: {"imuld", "imul", "imul", },
235: {"imulw", "imul", "imul", },
236: {"in", "in", "in", },
237: {"inc", "inc", "inc", },
238: {"incb", "inc", "inc", },
239: {"incl", "inc", "inc", },
240: {"incw", "inc", "inc", },
241: {"insb", "insb", "insb", },
242: {"insd", "insd", "insd", },
243: {"insw", "insw", "insw", },
244: {"int", "int", "int", },
245: {"into", "into", "into", },
246: {"iret", "iret", "iret", },
247: {"iretd", "iretf", "iretf", },
248: {"ja", "ja", "ja", },
249: {"jae", "jae", "jae", },
250: {"jael", "jae", "jae", },
251: {"jal", "ja", "ja", },
252: {"jb", "jb", "jb", },
253: {"jbe", "jbe", "jbe", },
254: {"jbel", "jbe", "jbe", },
255: {"jbl", "jb", "jb", },
256: {"jc", "jc", "jc", },
257: {"jcl", "jc", "jc", },
258: {"jcxz", "jcxz", "jcxz", },
259: {"je", "je", "je", },
260: {"jecxz", "jecxz", "jecxz", },
261: {"jel", "je", "je", },
262: {"jg", "jg", "jg", },
263: {"jge", "jge", "jge", },
264: {"jgel", "jge", "jge", },
265: {"jgl", "jg", "jg", },
266: {"jl", "jl", "jl", },
267: {"jle", "jle", "jle", },
268: {"jlel", "jle", "jle", },
269: {"jll", "jl", "jl", },
270: {"jmp", "jmp", "jmp", },
271: {"jmpf", "jmpf", "jmpf", },
272: {"jmpl", "jmp", "jmp", },
273: {"jna", "jna", "jna", },
274: {"jnae", "jnae", "jnae", },
275: {"jnael", "jnae", "jnae", },
276: {"jnal", "jna", "jna", },
277: {"jnb", "jnb", "jnb", },
278: {"jnbe", "jnbe", "jnbe", },
279: {"jnbel", "jnbe", "jnbe", },
280: {"jnbl", "jnb", "jnb", },
281: {"jnc", "jnc", "jnc", },
282: {"jncl", "jnc", "jnc", },
283: {"jne", "jne", "jne", },
284: {"jnel", "jne", "jne", },
285: {"jng", "jng", "jng", },
286: {"jnge", "jnge", "jnge", },
287: {"jngel", "jnge", "jnge", },
288: {"jngl", "jng", "jng", },
289: {"jnl", "jnl", "jnl", },
290: {"jnle", "jnle", "jnle", },
291: {"jnlel", "jnle", "jnle", },
292: {"jnll", "jnl", "jnl", },
293: {"jno", "jno", "jno", },
294: {"jnol", "jno", "jno", },
295: {"jnp", "jnp", "jnp", },
296: {"jnpl", "jnp", "jnp", },
297: {"jns", "jns", "jns", },
298: {"jnsl", "jns", "jns", },
299: {"jnz", "jnz", "jnz", },
300: {"jnzl", "jnz", "jnz", },
301: {"jo", "jo", "jo", },
302: {"jol", "jo", "jo", },
303: {"jp", "jp", "jp", },
304: {"jpe", "jpe", "jpe", },
305: {"jpel", "jpe", "jpe", },
306: {"jpl", "jp", "jp", },
307: {"jpo", "jpo", "jpo", },
308: {"jpol", "jpo", "jpo", },
309: {"js", "js", "js", },
310: {"jsl", "js", "js", },
311: {"jz", "jz", "jz", },
312: {"jzl", "jz", "jz", },
313: {"lahf", "lahf", "lahf", },
314: {"lds", "lds", "lds", },
315: {"lea", "lea", "lea", },
316: {"leave", "leave", "leave", },
317: {"les", "les", "les", },
318: {"lfs", "lfs", "lfs", },
319: {"lgdt", "lgdt", "lgdt", },
320: {"lgs", "lgs", "lgs", },
321: {"lidt", "lidt", "lidt", },
322: {"lldt", "lldt", "lldt", },
323: {"lmsw", "lmsw", "lmsw", },
324: {"lock", "lock", "lock", },
325: {"lodsb", "lodsb", "lodsb", },
326: {"lodsd", "lodsd", "lodsd", },
327: {"lodsw", "lodsw", "lodsw", },
328: {"loop", "loop", "loop", },
329: {"loope", "loope", "loope", },
330: {"loopne", "loopne", "loopne" },
331: {"loopnz", "loopnz", "loopnz" },
332: {"loopz", "loopz", "loopz", },
333: {"lss", "lss", "lss", },
334: {"ltr", "ltr", "ltr", },
335: {"mov", "mov", "mov", },
336: {"movb", "mov", "mov", },
337: {"movl", "mov", "mov", },
338: {"movsb", "movsb", "movsb", },
339: {"movsbl", "movsx", "movsx", },
340: {"movsbw", "movsx", "movsx", },
341: {"movsl", "movsd", "movsd", },
342: {"movsw", "movsw", "movsw", },
343: {"movswl", "movsx", "movsx", },
344: {"movw", "mov", "mov", },
345: {"movzbl", "movzx", "movzx", },
346: {"movzbw", "movzx", "movzx", },
347: {"movzwl", "movzx", "movzx", },
348: {"mul", "mul", "mul", },
349: {"mulb", "mul", "mul", },
350: {"muld", "mul", "mul", },
351: {"mulw", "mul", "mul", },
352: {"neg", "neg", "neg", },
353: {"negb", "neg", "neg", },
354: {"negw", "neg", "neg", },
355: {"negl", "neg", "neg", },
356: {"nop", "nop", "nop", },
357: {"not", "not", "not", },
358: {"notb", "not", "not", },
359: {"notw", "not", "not", },
360: {"notl", "not", "not", },
361: {"or", "or", "or", },
362: {"orb", "or", "or", },
363: {"orl", "or", "or", },
364: {"orw", "or", "or", },
365: {"out", "out", "out", },
366: {"outsb", "outsb", "outsb", },
367: {"outsd", "outsd", "outsd", },
368: {"outsw", "outsw", "outsw", },
369: {"pop", "pop", "pop", },
370: {"popa", "popa", "popa", },
371: {"popal", "popad", "popad", },
372: {"popl", "pop", "pop", },
373: {"popf", "popf", "popf", },
374: {"popfl", "popfd", "popfd", },
375: {"popw", "pop", "pop", },
376: {"push", "push", "push", },
377: {"pusha", "pusha", "pusha", },
378: {"pushal", "pushad", "pushad" },
379: {"pushl", "push\tdword", "push\tdword", },
380: {"pushf", "pushf", "pushf", },
381: {"pushfl", "pushfd", "pushfd" },
382: {"pushw", "push\tword", "push\tword", },
383: {"rclb", "rcl", "rcl", },
384: {"rcll", "rcl", "rcl", },
385: {"rclw", "rcl", "rcl", },
386: {"rcrb", "rcr", "rcr", },
387: {"rcrl", "rcr", "rcr", },
388: {"rcrw", "rcr", "rcr", },
389: {"rep", "rep", "rep", },
390: {"repe", "repe", "repe", },
391: {"repne", "repne", "repne", },
392: {"repnz", "repnz", "repnz", },
393: {"repz", "repz", "repz", },
394: {"ret", "ret", "ret", },
395: {"retd", "retd", "retd", },
396: {"retf", "retf", "retf", },
397: {"retfd", "retfd", "retfd", },
398: {"rolb", "rol", "rol", },
399: {"roll", "rol", "rol", },
400: {"rolw", "rol", "rol", },
401: {"rorb", "ror", "ror", },
402: {"rorl", "ror", "ror", },
403: {"rorw", "ror", "ror", },
404: {"sahf", "sahf", "sahf", },
405: {"salb", "sal", "sal", },
406: {"sall", "sal", "sal", },
407: {"salw", "sal", "sal", },
408: {"sarb", "sar", "sar", },
409: {"sarl", "sar", "sar", },
410: {"sarw", "sar", "sar", },
411: {"sbbb", "sbb ", "sbb ", },
412: {"sbbl", "sbb ", "sbb ", },
413: {"sbbw", "sbb ", "sbb ", },
414: {"scasb", "scasb", "scasb", },
415: {"scasd", "scasd", "scasd", },
416: {"scasw", "scasw", "scasw", },
417: {"seta", "seta", "seta", },
418: {"setae", "setae", "setae", },
419: {"setb", "setb", "setb", },
420: {"setbe", "setbe", "setbe", },
421: {"setc", "setc", "setc", },
422: {"sete", "sete", "sete", },
423: {"setg", "setg", "setg", },
424: {"setge", "setge", "setge", },
425: {"setl", "setl", "setl", },
426: {"setle", "setle", "setle", },
427: {"setna", "setna", "setna", },
428: {"setnae", "setnae", "setnae" },
429: {"setnb", "setnb", "setnb", },
430: {"setnbe", "setnbe", "setnbe" },
431: {"setnc", "setnc", "setnc", },
432: {"setne", "setne", "setne", },
433: {"setng", "setng", "setng", },
434: {"setnge", "setnge", "setnge" },
435: {"setnl", "setnl", "setnl", },
436: {"setnle", "setnle", "setnle" },
437: {"setno", "setno", "setno", },
438: {"setnp", "setnp", "setnp", },
439: {"setns", "setns", "setns", },
440: {"setnz", "setnz", "setnz", },
441: {"seto", "seto", "seto", },
442: {"setp", "setp", "setp", },
443: {"setpe", "setpe", "setpe", },
444: {"setpo", "setpo", "setpo", },
445: {"sets", "sets", "sets", },
446: {"setz", "setz", "setz", },
447: {"sgdt", "sgdt", "sgdt", },
448: {"shlb", "shl", "shl", },
449: {"shld", "shld", "shld", },
450: {"shll", "shl", "shl", },
451: {"shlw", "shl", "shl", },
452: {"shrb", "shr", "shr", },
453: {"shrd", "shrd", "shrd", },
454: {"shrl", "shr", "shr", },
455: {"shrw", "shr", "shr", },
456: {"sidt", "sidt", "sidt", },
457: {"sldt", "sldt", "sldt", },
458: {"smsw", "smsw", "smsw", },
459: {"stc", "stc", "stc", },
460: {"std", "std", "std", },
461: {"sti", "sti", "sti", },
462: {"stosb", "stosb", "stosb", },
463: {"stosl", "stosd", "stosd", },
464: {"stosw", "stosw", "stosw", },
465: {"subb", "sub", "sub", },
466: {"subl", "sub", "sub", },
467: {"subw", "sub", "sub", },
468: {"testb", "test", "test", },
469: {"testl", "test", "test", },
470: {"testw", "test", "test", },
471: {"verr", "verr", "verr", },
472: {"verw", "verw", "verw", },
473: {"wait", "wait", "wait", },
474: {"xchg", "xchg", "xchg", },
475: {"xchgb", "xchg", "xchg", },
476: {"xchgw", "xchg", "xchg", },
477: {"xchgl", "xchg", "xchg", },
478: {"xlat", "xlat", "xlat", },
479: {"xlatb", "xlatb", "xlatb", },
480: {"xorb", "xor", "xor", },
481: {"xorl", "xor", "xor", },
482: {"xorw", "xor", "xor", },
483: };
484:
485: #define SF 0x80
486: #define ZF 0x40
487: #define YF 0x20
488: #define HF 0x10
489: #define XF 0x08
490: #define PF 0x04
491: #define VF PF
492: #define NF 0x02
493: #define CF 0x01
494:
495: #define INT_IRQ 0x01
496: #define INT_NMI 0x80
497:
498: #define zF M(1,"z80_AF",0,0,0,0)
499: #define zA M(1,"z80_AF",0,1,0,0)
500: #define zAF M(2,"z80_AF",0,0,0,0)
501: #define zAF32 M(4,"z80_AF",0,0,0,0)
502:
503: #define zC M(1,"z80_BC",0,0,0,0)
504: #define zB M(1,"z80_BC",0,1,0,0)
505: #define zBC M(2,"z80_BC",0,0,0,0)
506: #define zBC32 M(4,"z80_BC",0,0,0,0)
507:
508: #define zE M(1,"z80_DE",0,0,0,0)
509: #define zD M(1,"z80_DE",0,1,0,0)
510: #define zDE M(2,"z80_DE",0,0,0,0)
511: #define zDE32 M(4,"z80_DE",0,0,0,0)
512:
513: #define zL M(1,"z80_HL",0,0,0,0)
514: #define zH M(1,"z80_HL",0,1,0,0)
515: #define zHL M(2,"z80_HL",0,0,0,0)
516: #define zHL32 M(4,"z80_HL",0,0,0,0)
517:
518: #define zLX M(1,"z80_IX",0,0,0,0)
519: #define zHX M(1,"z80_IX",0,1,0,0)
520: #define zIX M(2,"z80_IX",0,0,0,0)
521: #define zIX32 M(4,"z80_IX",0,0,0,0)
522:
523: #define zLY M(1,"z80_IY",0,0,0,0)
524: #define zHY M(1,"z80_IY",0,1,0,0)
525: #define zIY M(2,"z80_IY",0,0,0,0)
526: #define zIY32 M(4,"z80_IY",0,0,0,0)
527:
528: #define zPCL M(1,"z80_PC",0,0,0,0)
529: #define zPCH M(1,"z80_PC",0,1,0,0)
530: #define zPC M(2,"z80_PC",0,0,0,0)
531: #define zPC32 M(4,"z80_PC",0,0,0,0)
532:
533: #define zSPL M(1,"z80_SP",0,0,0,0)
534: #define zSPH M(1,"z80_SP",0,1,0,0)
535: #define zSP M(2,"z80_SP",0,0,0,0)
536: #define zSP32 M(4,"z80_SP",0,0,0,0)
537:
538: #define zF2 M(1,"z80_AF2",0,0,0,0)
539: #define zA2 M(1,"z80_AF2",0,1,0,0)
540: #define zAF2 M(2,"z80_AF2",0,0,0,0)
541: #define zBC2 M(2,"z80_BC2",0,0,0,0)
542: #define zDE2 M(2,"z80_DE2",0,0,0,0)
543: #define zHL2 M(2,"z80_HL2",0,0,0,0)
544:
545: #define zR M(1,"z80_R",0,0,0,0)
546: #define zR2 M(1,"z80_R2",0,0,0,0)
547: #define zIFF1 M(1,"z80_IFF1",0,0,0,0)
548: #define zIFF2 M(1,"z80_IFF2",0,0,0,0)
549: #define zHALT M(1,"z80_HALT",0,0,0,0)
550: #define zIM M(1,"z80_IM",0,0,0,0)
551: #define zI M(1,"z80_I",0,0,0,0)
552: #define pending M(1,"z80_pending_irq",0,0,0,0)
553: #define vector_d M(4,"z80_vector",0,0,0,0)
554: #define vector_w M(2,"z80_vector",0,0,0,0)
555: #define vector_h M(1,"z80_vector",0,2,0,0)
556: #define irq_max M(4,"z80_irq_max",0,0,0,0)
557: #define request_irq M(4,"z80_request_irq",0,0,0,0)
558: #define service_irq M(4,"z80_service_irq",0,0,0,0)
559: #define int_state(n) M(4,"z80_int_state",0,0,n,4)
560: #define irq(n,o) M(4,"z80_irq",n,o,0,0)
561: #define nmi_state M(4,"z80_nmi_state",0,0,0,0)
562: #define irq_state M(4,"z80_irq_state",0,0,0,0)
563: #define irq_callback M(4,"z80_irq_callback",0,0,0,0)
564: #define zEA M(4,"z80_EA",0,0,0,0)
565: #define zMB M(1,"z80_MB",0,0,0,0)
566: #define zDAA(n) M(2,"z80_daa",0,0,n,2)
567:
568: #define zICOUNT M(4,"_Z80_ICount",0,0,0,0)
569: #define zITOTAL M(4,"z80_itotal",0,0,0,0)
570: #define zIEXTRN M(4,"z80_iextrn",0,0,0,0)
571:
572: #define PREVPC M(4,"_previouspc",0,0,0,0)
573: #define DEBUG M(1,"_mame_debug",0,0,0,0)
574: #define BANKBASE(n) M(4,"_cpu_bankbase",0,0,n,4)
575: #define MRHARD M(4,"_cur_mrhard",0,0,0,0)
576: #define READHW(n,a) M(1,"_readhardware",n,-0x4000,a,1)
577: #define READOFFSET(n) M(4,"_memoryreadoffset",0,0,n,4)
578: #define READHANDLER(n) M(4,"_memoryreadhandler",0,0,n,4)
579:
580: #define MWHARD M(4,"_cur_mwhard",0,0,0,0)
581: #define WRITEHW(n,a) M(1,"_writehardware",n,-0x4000,a,1)
582: #define WRITEOFFSET(n) M(4,"_memorywriteoffset",0,0,n,4)
583: #define WRITEHANDLER(n) M(4,"_memorywritehandler",0,0,n,4)
584:
585: #define ROM M(4,"_ROM",0,0,0,0)
586: #define RAM M(4,"_RAM",0,0,0,0)
587: #define OP_ROM M(4,"_OP_ROM",0,0,0,0)
588: #define OP_RAM M(4,"_OP_RAM",0,0,0,0)
589:
590: /* Z80 accu and flags mapped to x86 (E)AX register */
591: #define F AH
592: #define A AL
593: #define AF AX
594: #define AF32 EAX
595:
596: /* Z80 HL mapped to x86 (E)BX register */
597: #define L BL
598: #define H BH
599: #define HL BX
600: #define HL32 EBX
601:
602: /* Z80 program counter mapped to x86 (E)SI register */
603: #define pc32 esi
604: #define PC SI
605: #define PC32 ESI
606:
607: #include "z80daa.h"
608:
609: void emit(const char *fmt, ...)
610: {
611: va_list arg;
612: va_start(arg,fmt);
613: vfprintf(output, fmt, arg);
614: va_end(arg);
615: fprintf(output, "\n");
616: }
617:
618: void com(const char *fmt, ...)
619: {
620: va_list arg;
621: int len = 0;
622: if (fmt) {
623: if (as == GAS)
624: len += fprintf(output, "/* ");
625: else
626: len += fprintf(output, "; ");
627: va_start(arg, fmt);
628: len += vfprintf(output, fmt, arg);
629: va_end(arg);
630: if (as == GAS)
631: {
632: while (len < 72)
633: {
634: fprintf(output, "\t");
635: len += 8 - (len & 7);
636: }
637: fprintf(output, " */");
638: }
639: }
640: fprintf(output, "\n");
641: }
642:
643: /* return an immediate decimal byte size value */
644: const char *B(int value)
645: {
646: static char B_str[32][16];
647: static int which = 0;
648: char *dst;
649:
650: which = ++which % 32;
651: dst = B_str[which];
652: if (as == GAS)
653: sprintf(dst, "$%d", value);
654: else
655: sprintf(dst, "byte %d", value);
656: return B_str[which];
657: }
658:
659: /* return an immediate decimal value */
660: const char *D(int value)
661: {
662: static char D_str[32][16];
663: static int which = 0;
664: char *dst;
665:
666: which = ++which % 32;
667: dst = D_str[which];
668: if (as == GAS)
669: sprintf(dst, "$%d", value);
670: else
671: sprintf(dst, "%d", value);
672: return D_str[which];
673: }
674:
675: /* return an immediate hexadecimal value */
676: const char *X(int value)
677: {
678: static char X_str[32][16];
679: static int which = 0;
680: char *dst;
681:
682: which = ++which % 32;
683: dst = X_str[which];
684: if (as == GAS)
685: sprintf(dst, "$0x%x", value);
686: else
687: sprintf(dst, "0%xh", value);
688: return X_str[which];
689: }
690:
691: /* return a symbol with 'short' distance modifier (for NASM) */
692: char *LS(const char *symbol)
693: {
694: static char buffer[128];
695: if (as == NASM)
696: sprintf(buffer, "short %s", symbol);
697: else
698: sprintf(buffer, "%s", symbol);
699: return buffer;
700: }
701:
702: /* return a symbol with 'near' distance modifier (for NASM) */
703: char *LN(const char *symbol)
704: {
705: static char buffer[128];
706: if (as == NASM)
707: sprintf(buffer, "near %s", symbol);
708: else
709: sprintf(buffer, "%s", symbol);
710: return buffer;
711: }
712:
713: /* emit a symbol and optional comment */
714: void S(const char *symbol, const char *comment, ...)
715: {
716: va_list arg;
717: char buffer[256];
718: char fmt[128];
719: int len = 0;
720:
721: fmt[0] = '\0';
722: if (symbol)
723: len += sprintf(fmt, "%s:", symbol);
724: if (comment) {
725: while (len < 32) {
726: strcat(fmt,"\t");
727: len += 8 - (len & 7);
728: }
729: if (as == GAS) {
730: strcat(fmt,"/* ");
731: len += 3;
732: } else {
733: strcat(fmt,"; ");
734: len += 2;
735: }
736: len += strlen(comment);
737: strcat(fmt, comment);
738: }
739: va_start(arg, comment);
740: len = len - strlen(fmt) + vsprintf(buffer, fmt, arg);
741: va_end(arg);
742:
743: if (comment && as == GAS) {
744: while (len < 72) {
745: strcat(buffer,"\t");
746: len += 8 - (len & 7);
747: }
748: strcat(buffer, "*/");
749: }
750: fprintf(output, "%s\n", buffer);
751: }
752:
753: /* emit an symbol, x86 instruction, dst and src operands and comment */
754: void I(const char *sym, x86_token t, const char *dst, const char *src, const char *comment)
755: {
756: char buffer[32], *p;
757: int len = 0, first_tab;
758:
759: first_tab = (t < align) ? 24 : 8;
760: if (sym)
761: len += fprintf(output, "%s:", sym);
762:
763: strcpy(buffer, x86_token_str[t][as]);
764: if (as == NASM) {
765: p = strstr(buffer,"\tdword"); /* remove 'dword' once if it occurs twice */
766: if (p && ((src && !strncmp(src,"dword",5)) || (dst && !strncmp(dst,"dword",5))))
767: *p = '\0';
768: p = strstr(buffer,"\tword"); /* remove 'word' once if it occurs twice */
769: if (p && ((src && !strncmp(src,"word",4)) || (dst && !strncmp(dst,"word",4))))
770: *p = '\0';
771: }
772:
773: do {
774: len = (len | 7) + 1;
775: fprintf(output, "\t");
776: } while (len < first_tab);
777:
778: len += fprintf(output, "%s", buffer);
779: if (dst) {
780: do {
781: len = (len | 7) + 1;
782: fprintf(output, "\t");
783: } while (len < first_tab + 8);
784: if (src) {
785: if (as == GAS)
786: len += fprintf(output, "%s, %s", src, dst);
787: else
788: len += fprintf(output, "%s, %s", dst, src);
789: } else {
790: len += fprintf(output, "%s", dst);
791: }
792: } else {
793: if (src) {
794: do {
795: len = (len | 7) + 1;
796: fprintf(output, "\t");
797: } while (len < first_tab + 8);
798: len += fprintf(output, "%s", src);
799: }
800: }
801: if (comment) {
802: do {
803: fprintf(output, "\t");
804: len = (len | 7) + 1;
805: } while (len < 48);
806: if (as == GAS) {
807: len += fprintf(output, "/* %s", comment);
808: while (len < 72) {
809: fprintf(output, "\t");
810: len = (len | 7) + 1;
811: }
812: len += fprintf(output, " */");
813: } else {
814: len += fprintf(output, "; %s", comment);
815: }
816: }
817: fprintf(output, "\n");
818: }
819:
820: /* return a memory reference */
821: const char *M(int size, const char *base, x86_regs r1, int offs, x86_regs r2, int mult)
822: {
823: static char mem_str[32][64];
824: static int which = 0;
825: char *dst;
826:
827: which = ++which % 32;
828: dst = mem_str[which];
829: switch (as) {
830: case GAS:
831: if (base) {
832: dst += sprintf(dst, "%s", base);
833: if (offs)
834: dst += sprintf(dst, "%+d", offs);
835: } else {
836: if (offs)
837: dst += sprintf(dst, "%d", offs);
838: }
839: if (r1) {
840: dst += sprintf(dst, "(%s", x86_rstr[r1][as]);
841: if (r2)
842: dst += sprintf(dst, ",%s", x86_rstr[r2][as]);
843: if (mult)
844: dst += sprintf(dst, ",%d", mult);
845: dst += sprintf(dst, ")");
846: } else if (r2) {
847: dst += sprintf(dst, "(,%s", x86_rstr[r2][as]);
848: if (mult)
849: dst += sprintf(dst, ",%d", mult);
850: dst += sprintf(dst, ")");
851: }
852: break;
853:
854: case NASM:
855: switch (size) {
856: case 1:
857: dst += sprintf(dst, "byte[");
858: break;
859: case 2:
860: dst += sprintf(dst, "word[");
861: break;
862: case 4:
863: dst += sprintf(dst, "dword[");
864: break;
865: default: /* no size prefix */
866: dst += sprintf(dst, "[");
867: }
868: if (base)
869: dst += sprintf(dst, "%s", base);
870: if (r1) {
871: if (base)
872: dst += sprintf(dst, "+");
873: dst += sprintf(dst, "%s", x86_rstr[r1][as]);
874: if (offs)
875: dst += sprintf(dst, "%+d", offs);
876: if (r2) {
877: dst += sprintf(dst, "+%s", x86_rstr[r2][as]);
878: if (mult && mult > 1)
879: dst += sprintf(dst, "*%d", mult);
880: }
881: } else if (r2) {
882: if (base)
883: dst += sprintf(dst, "+");
884: dst += sprintf(dst, "%s", x86_rstr[r2][as]);
885: if (mult && mult > 1)
886: dst += sprintf(dst, "*%d", mult);
887: } else {
888: if (offs) {
889: if (base)
890: dst += sprintf(dst, "%+d", offs);
891: else
892: dst += sprintf(dst, "%s", X(offs));
893: }
894: }
895: dst += sprintf(dst, "]");
896: break;
897:
898: case TASM:
899: switch (size) {
900: case 1:
901: dst += sprintf(dst, "byte ptr [");
902: break;
903: case 2:
904: dst += sprintf(dst, "word ptr [");
905: break;
906: case 4:
907: dst += sprintf(dst, "dword ptr [");
908: break;
909: default: /* no size prefix */
910: dst += sprintf(dst, "[");
911: }
912: if (base)
913: dst += sprintf(dst, "%s", base);
914: if (r1) {
915: if (base)
916: dst += sprintf(dst, "+");
917: dst += sprintf(dst, "%s", x86_rstr[r1][as]);
918: if (offs)
919: dst += sprintf(dst, "%+d", offs);
920: if (r2) {
921: dst += sprintf(dst, "+%s", x86_rstr[r2][as]);
922: if (mult)
923: dst += sprintf(dst, "*%d", mult);
924: }
925: } else if (r2) {
926: if (base)
927: dst += sprintf(dst, "+");
928: dst += sprintf(dst, "%s", x86_rstr[r2][as]);
929: if (mult)
930: dst += sprintf(dst, "*%d", mult);
931: } else {
932: if (offs) {
933: if (base)
934: dst += sprintf(dst, "%+d", offs);
935: else
936: dst += sprintf(dst, "%s", X(offs));
937: }
938: }
939: dst += sprintf(dst, "]");
940: break;
941: }
942: return mem_str[which];
943: }
944:
945: /* return a x86 register name */
946: const char *R(x86_regs rg)
947: {
948: if (as == GAS) {
949: switch (rg) {
950: case none: return "none";
951: case al: return "%al";
952: case ah: return "%ah";
953: case cl: return "%cl";
954: case ch: return "%ch";
955: case dl: return "%dl";
956: case dh: return "%dh";
957: case bl: return "%bl";
958: case bh: return "%bh";
959: case ax: return "%ax";
960: case cx: return "%cx";
961: case dx: return "%dx";
962: case bx: return "%bx";
963: case si: return "%si";
964: case di: return "%di";
965: case bp: return "%bp";
966: case sp: return "%sp";
967: case eax: return "%eax";
968: case ecx: return "%ecx";
969: case edx: return "%edx";
970: case ebx: return "%ebx";
971: case esi: return "%esi";
972: case edi: return "%edi";
973: case ebp: return "%ebp";
974: case esp: return "%esp";
975: }
976: } else {
977: switch (rg) {
978: case none: return "none";
979: case al: return "al";
980: case ah: return "ah";
981: case cl: return "cl";
982: case ch: return "ch";
983: case dl: return "dl";
984: case dh: return "dh";
985: case bl: return "bl";
986: case bh: return "bh";
987: case ax: return "ax";
988: case cx: return "cx";
989: case dx: return "dx";
990: case bx: return "bx";
991: case si: return "si";
992: case di: return "di";
993: case bp: return "bp";
994: case sp: return "sp";
995: case eax: return "eax";
996: case ecx: return "ecx";
997: case edx: return "edx";
998: case ebx: return "ebx";
999: case esi: return "esi";
1000: case edi: return "edi";
1001: case ebp: return "ebp";
1002: case esp: return "esp";
1003: }
1004: }
1005: return "xx";
1006: }
1007:
1008: const char *O(const char *symbol)
1009: {
1010: static char ofs_str[32][32];
1011: static int which = 0;
1012: char *dst;
1013:
1014: which = ++which % 32;
1015: dst = ofs_str[which];
1016: switch (as) {
1017: case GAS: /* GAS: $ indicates immediate (address of) */
1018: sprintf(dst, "$%s", symbol);
1019: break;
1020: case NASM: /* NASM: only the name w/o square brackets */
1021: sprintf(dst, "%s", symbol);
1022: break;
1023: case TASM: /* TASM: offset name */
1024: sprintf(dst, "offset %s", symbol);
1025: break;
1026: }
1027: return ofs_str[which];
1028: }
1029:
1030: int str(char *dst, const char *src)
1031: {
1032: int argc = 0;
1033: char strdelim = '"';
1034:
1035: if (as == GAS) {
1036: *dst++ = strdelim;
1037: while (*src) {
1038: switch (*src) {
1039: case '\b': /* backspace */
1040: dst += sprintf(dst, "\\010");
1041: break;
1042: case '\t': /* tab */
1043: dst += sprintf(dst, "\\011");
1044: break;
1045: case '\n': /* newline */
1046: dst += sprintf(dst, "\\012");
1047: break;
1048: case '\r': /* carriage return */
1049: dst += sprintf(dst, "\\015");
1050: break;
1051: default:
1052: if (src[0] == '%' && src[1] != '%')
1053: argc++;
1054: *dst++ = *src;
1055: }
1056: src++;
1057: }
1058: strcpy(dst, "\\000\"");
1059: } else {
1060: char len = 0;
1061: int instr = 0;
1062:
1063: while (*src) {
1064: switch (*src) {
1065: case '\b': /* backspace */
1066: case '\t': /* tab */
1067: case '\n': /* line feed */
1068: case '\r': /* new line */
1069: if (instr) {
1070: *dst++ = strdelim;
1071: len++;
1072: instr = 0;
1073: }
1074: if (len) {
1075: *dst++ = ',';
1076: len++;
1077: }
1078: dst += sprintf(dst, "%d", *src);
1079: break;
1080: default:
1081: if (src[0] == '%' && src[1] != '%')
1082: argc++;
1083: if (!instr) {
1084: if (len) {
1085: *dst++ = ',';
1086: len++;
1087: }
1088: *dst++ = strdelim;
1089: len++;
1090: instr = 1;
1091: }
1092: *dst++ = *src;
1093: len++;
1094: }
1095: src++;
1096: }
1097: if (instr) {
1098: *dst++ = strdelim;
1099: len++;
1100: }
1101: if (len)
1102: *dst++ = ',';
1103: strcpy(dst, "0");
1104: }
1105: return argc;
1106: }
1107:
1108: void debug(int level, char *fmt, ...)
1109: {
1110: static int dbg_cnt = 0;
1111: va_list args;
1112:
1113: if (verbose >= level) {
1114: int i, argc;
1115: char dbgtxt[16], dbgend[16], format[128];
1116: char *arg, pusharg[32][64];
1117:
1118: argc = str(format, fmt);
1119: dbg_cnt++;
1120: sprintf(dbgtxt, "L%04x", dbg_cnt);
1121: sprintf(dbgend, "L%04xx", dbg_cnt);
1122: I(0, data, 0, 0, 0);
1123: I(dbgtxt, dm, format, 0, 0);
1124: I(0, text, 0, 0, 0);
1125: va_start(args, fmt);
1126: for (i = 0; i < argc; i++) {
1127: arg = va_arg(args, char *);
1128: sprintf(pusharg[i],"\t%s\t%s\n",x86_token_str[pushl][as],arg);
1129: }
1130: va_end(args);
1131: I(0,testl, M(4,"_errorlog",0,0,0,0), D(-1), 0);
1132: I(0,je, LS(dbgend), 0, 0);
1133: I(0,pushad,0,0,0);
1134: for (i = argc - 1; i >= 0; i--)
1135: fputs(pusharg[i], output);
1136: I(0,pushl, O(dbgtxt), 0, 0);
1137: I(0,pushl, M(4,"_errorlog",0,0,0,0), 0, 0);
1138: I(0,call, "_fprintf", 0, 0);
1139: I(0,addl, ESP, D((argc + 2) * 4),0);
1140: I(0,popad, 0, 0, 0);
1141: S(dbgend,0);
1142: }
1143: }
1144:
1145: static void dumpregs(void)
1146: {
1147: debug(8,"AF:%04x BC:%04x DE:%04x HL:%04x IX:%04x IY:%04x SP:%04x PC:%04x PC:%04x\n",
1148: zAF,zBC,zDE,zHL,zIX,zIY,zSP,zPC);
1149: }
1150:
1151:
1152: static void pad(int alignment)
1153: {
1154: char buffer[4+1];
1155: com(0);
1156: if (alignment) {
1157: if (as == GAS) {
1158: sprintf(buffer, "%d", alignment);
1159: I(0,align,buffer,0,0);
1160: } else {
1161: sprintf(buffer, "%d", 2<<alignment);
1162: I(0,align,buffer,0,0);
1163: }
1164: }
1165: }
1166:
1167: static void save_af(void)
1168: {
1169: I(0,movb, zF, F, "save F");
1170: I(0,movb, zA, A, "save A");
1171: }
1172:
1173: static void restore_af(void)
1174: {
1175: I(0,movzbl, AF32, zA, "get A");
1176: I(0,movb, F, zF, "get F");
1177: }
1178:
1179: static void save_z80(int opsize)
1180: {
1181: I(0,movw, zPC, PC, "save PC");
1182: I(0,movw, zHL, HL, "save HL");
1183: #if CALC_PREVPC
1184: if (opsize) {
1185: if ( opsize == +1 )
1186: I(0,decl, PC32, 0, "subtract opcode size from PC");
1187: else
1188: I(0,subl, PC32, B(opsize), "subtract opcode size from PC");
1189: I(0,movl, PREVPC, PC32, "store previous PC");
1190: }
1191: #endif
1192: }
1193:
1194: static void restore_z80(void)
1195: {
1196: I(0,movzwl, PC32, zPC, "get PC");
1197: I(0,movzwl, HL32, zHL, "get HL");
1198: }
1199:
1200: /*************************************************************************
1201: * MOVB
1202: * Move register/memory from src to dst
1203: *************************************************************************/
1204: static void MOVB( const char *dst, const char *src, const char *comment, ... )
1205: {
1206: char buffer[128+1];
1207: va_list arg;
1208: va_start(arg, comment);
1209: vsprintf(buffer, comment, arg);
1210: va_end(arg);
1211:
1212: if (!strcmp(dst, src))
1213: return;
1214: if (!strcmp(dst, AL) || !strcmp(src, AL) ||
1215: !strcmp(dst, AH) || !strcmp(src, AH) ||
1216: !strcmp(dst, CL) || !strcmp(src, CL) ||
1217: !strcmp(dst, CH) || !strcmp(src, CH) ||
1218: !strcmp(dst, DL) || !strcmp(src, DL) ||
1219: !strcmp(dst, DH) || !strcmp(src, DH) ||
1220: !strcmp(dst, BL) || !strcmp(src, BL) ||
1221: !strcmp(dst, BH) || !strcmp(src, BH)) {
1222: if (!strcmp(dst,EAX) || !strcmp(dst,ECX) ||
1223: !strcmp(dst,EDX) || !strcmp(dst,EBX) ||
1224: !strcmp(dst,EBP) || !strcmp(dst,ESI) ||
1225: !strcmp(dst,EDI) || !strcmp(dst,ESP)) {
1226: /* zero extend byte register */
1227: I(0,movzbl, dst, src, buffer);
1228: } else {
1229: /* dst and src are byte register */
1230: I(0,movb, dst, src, buffer);
1231: }
1232: } else {
1233: if (!strcmp(dst,EAX) || !strcmp(dst,ECX) ||
1234: !strcmp(dst,EDX) || !strcmp(dst,EBX) ||
1235: !strcmp(dst,EBP) || !strcmp(dst,ESI) ||
1236: !strcmp(dst,EDI) || !strcmp(dst,ESP)) {
1237: /* zero extend memory byte */
1238: I(0,movzbl, dst, src, buffer);
1239: } else {
1240: /* memory to memory byte transfer */
1241: I(0,movb, CL, src, buffer);
1242: I(0,movb, dst, CL, 0);
1243: }
1244: }
1245: }
1246:
1247: /*************************************************************************
1248: * ADJUST_PC
1249: * increment/decrement or adjust program counter (PC)
1250: *************************************************************************/
1251: void ADJUST_PC( int offset )
1252: {
1253: if (offset == +1)
1254: I(0,incl, PC32, 0, "increment PC");
1255: else
1256: if (offset == -1)
1257: I(0,decl, PC32, 0, "decrement PC");
1258: else
1259: I(0,addl, PC32, B(offset), "adjust PC");
1260: }
1261:
1262: /*************************************************************************
1263: * ROP
1264: * Read opcode from OP_ROM at PC
1265: *************************************************************************/
1266: static void ROP( void )
1267: {
1268: I(0,movl, EDI, OP_ROM, "get OP_ROM base");
1269: I(0,movzbl, ECX, M(1,0,edi,0,pc32,1),"read opcode byte");
1270: ADJUST_PC(+1);
1271: }
1272:
1273: /*************************************************************************
1274: * ARG
1275: * dst where to store the result
1276: * Get an 8 bit argument from OP_RAM at PC
1277: *************************************************************************/
1278: static void ARG( const char *dst )
1279: {
1280: I(0,movl, EDI, OP_RAM, "get OP_RAM base");
1281: MOVB( dst, M(1,0,edi,0,pc32,1), "read opcode argument byte");
1282: ADJUST_PC(+1);
1283: }
1284:
1285: /*************************************************************************
1286: * ARG16
1287: * dst where to store the result
1288: * Get an 16 bit argument from OP_RAM at PC
1289: *************************************************************************/
1290: static void ARG16(const char *dst)
1291: {
1292: I(0,movl, EDI, OP_RAM, "get OP_RAM base");
1293: if (!strcmp(dst, EAX) || !strcmp(dst, ECX) ||
1294: !strcmp(dst, EDX) || !strcmp(dst, EBX) ||
1295: !strcmp(dst, ESI) || !strcmp(dst, EDI) ||
1296: !strcmp(dst, EBP) || !strcmp(dst, ESP)) {
1297: I(0,movzwl, dst, M(2,0,edi,0,pc32,1), "read opcode argument word (zero extend)");
1298: } else {
1299: I(0,movzwl, ECX, M(2,0,edi,0,pc32,1), "read opcode argument word (zero extend)");
1300: I(0,movl, dst, ECX, "store result");
1301: }
1302: if (strcmp(dst, PC32)) /* not loaded PC itself? */
1303: ADJUST_PC(+2);
1304: }
1305:
1306: /*************************************************************************
1307: * REL
1308: * Get an sign extended byte argument from OP_RAM at PC into ECX
1309: *************************************************************************/
1310: static void REL( void )
1311: {
1312: I(0,movl, EDI, OP_RAM, "get OP_RAM base");
1313: I(0,movsbl, ECX, M(1,0,edi,0,pc32,1),"read 2's complement offset");
1314: ADJUST_PC(+1);
1315: }
1316:
1317: /*************************************************************************
1318: * OFS
1319: * base IX or IY register (dword[z80_IX] or dword[z80_IY])
1320: * Build index register plus ofs8 (2's complement offset)
1321: *************************************************************************/
1322: static void OFS(const char *base)
1323: {
1324: I(0,movl, EDI, OP_RAM, "get OP_RAM base");
1325: I(0,movsbl, ECX, M(1,0,edi,0,pc32,1),"read opcode argument byte");
1326: I(0,addl, ECX, base, "add index register");
1327: I(0,movzwl, EBP, CX, "16 address bits");
1328: ADJUST_PC(+1);
1329: }
1330:
1331: /*************************************************************************
1332: * CHANGE_PC
1333: * Check if cur_mrhard for the new PC has changed and call
1334: * cpu_setOPbase16 if necessary
1335: *************************************************************************/
1336: static void CHANGE_PC( void )
1337: {
1338: static int chgpc = 0;
1339: char symbol[32+1];
1340: chgpc++;
1341: sprintf(symbol,"chgpc_%02x", chgpc);
1342: I(0,movzwl, ECX, PC, "get PC to ECX");
1343: I(0,movl, PC32, ECX, "make PC 16 bit again");
1344: I(0,movl, EDI, MRHARD, 0);
1345: I(0,shrl, ECX, D(ABITS), ">> (ABITS2_16 + ABITS_MIN_16)");
1346: I(0,movb, CL, M(1,0,edi,0,ecx,1), "get cur_mrhard[index]");
1347: I(0,cmpb, CL, M(1,"_ophw",0,0,0,0), "changed?");
1348: I(0,je, LS(symbol),0, "no, skip");
1349: save_af();
1350: save_z80( 0 );
1351: I(0,pushl, PC32, 0, 0);
1352: I(0,call, "_cpu_setOPbase16",0, 0);
1353: I(0,addl, ESP, B(4), 0);
1354: restore_z80();
1355: restore_af();
1356: S(symbol,0);
1357: }
1358:
1359: /*************************************************************************
1360: * RBYTE
1361: * dst where to store the result
1362: * src memory address
1363: * Read a byte from memory
1364: *************************************************************************/
1365: static void RBYTE( int opsize, const char *val, const char *src )
1366: {
1367: char symbol[15+1];
1368: rbyte++;
1369: sprintf(symbol,"rbyte%d", opsize*CALC_PREVPC);
1370: if (strcmp(src, EBP))
1371: I(0,movl, EBP, src, "memory address to EBP");
1372: I(0,call, symbol, 0, "read byte");
1373: if( strcmp(val, EDX) && strcmp(val, DX) && strcmp(val, DL) )
1374: I(0,movl, val, EDX, "store result");
1375: }
1376:
1377: /*************************************************************************
1378: * RWORD
1379: * val where to store the result
1380: * src memory address
1381: * Read a word from memory
1382: *************************************************************************/
1383: static void RWORD( int opsize, const char *val, const char *src )
1384: {
1385: char symbol[15+1];
1386: rword++;
1387: sprintf(symbol,"rword%d", opsize*CALC_PREVPC);
1388: if (strcmp(src, EBP))
1389: I(0,movl, EBP, src, "memory address to EBP");
1390: I(0,call, symbol, 0, "read word");
1391: if( strcmp(val, EDX) && strcmp(val, DX) && strcmp(val, DL) )
1392: I(0,movl, val, EDX, "store result");
1393: }
1394:
1395: /*************************************************************************
1396: * WBYTE
1397: * dst memory address
1398: * val value to store
1399: * Write a byte to memory
1400: *************************************************************************/
1401: static void WBYTE( int opsize, const char *dst, const char *val )
1402: {
1403: char symbol[15+1];
1404: wbyte++;
1405: sprintf(symbol,"wbyte%d", opsize*CALC_PREVPC);
1406: if (strcmp(dst, EBP))
1407: I(0,movl, EBP, dst, "memory address to EBP");
1408: if (strcmp(val, EDX))
1409: I(0,movl, EDX, val, "get value to EDX");
1410: I(0,call, symbol, 0, "write byte");
1411: }
1412:
1413: /*************************************************************************
1414: * WWORD
1415: * dst memory address
1416: * val value to store
1417: * Write a word to memory
1418: *************************************************************************/
1419: static void WWORD( int opsize, const char *dst, const char *val )
1420: {
1421: char symbol[15+1];
1422: wword++;
1423: sprintf(symbol,"wword%d", opsize*CALC_PREVPC);
1424: if (strcmp(dst, EBP))
1425: I(0,movl, EBP, dst, "memory address to EBP");
1426: if (strcmp(val, EDX))
1427: I(0,movl, EDX, val, "get value to EDX");
1428: I(0,call, symbol, 0, "write word");
1429: }
1430:
1431: static void PUSH( int opsize, const char *src )
1432: {
1433: char reg[32+1];
1434: strcpy(reg, src);
1435: I(0,subw, zSP, B(2), 0);
1436: WWORD( opsize, zSP32, reg );
1437: }
1438:
1439: static void POP( int opsize, const char *dst )
1440: {
1441: char reg[32+1];
1442: strcpy(reg, dst);
1443: RWORD( opsize, reg, zSP32 );
1444: I(0,addw, zSP, B(2), 0);
1445: }
1446:
1447: static char *beg_opcode(int cycles, const char *symbol, const char *comment, ...)
1448: {
1449: static char endfunc[32];
1450: char begfunc[32], *dst = begfunc;
1451: char buffer[256];
1452: va_list args;
1453:
1454: #if GLOBL
1455: /* put an underscore in front of the symbol */
1456: sprintf(dst, "_%s", symbol);
1457: I(0,globl,begfunc,0,0);
1458: #else
1459: /* extract the symbol */
1460: strcpy(dst, symbol);
1461: #endif
1462:
1463: /* symbol to put at the end of the function */
1464: sprintf(endfunc, "L%s", begfunc);
1465:
1466: if (comment) {
1467: va_start(args, comment);
1468: vsprintf(buffer, comment, args);
1469: va_end(args);
1470: com("***** %s", buffer);
1471: }
1472: pad(align_funcs);
1473: S(begfunc,0);
1474: if (cycles)
1475: I(0,subl, zICOUNT, B(cycles), "subtract from ICount");
1476: if (strncmp(symbol,"xx",2)) /* M1 type opcode fetch? */
1477: I(0,incb, zR, 0, "increment R register once");
1478:
1479: opcodes++;
1480:
1481: return endfunc;
1482: }
1483:
1484: static void end_opcode(const char *op_base)
1485: {
1486: if (!strcmp(op_base, "z_op")) {
1487: I(0,orl, zICOUNT, B(0), "all cycles used up?");
1488: I(0,jle, LN("z80_execute_done"),0, 0);
1489: #if (!CALC_PREVPC)
1490: I(0,movl, PREVPC, PC32, "store previous PC");
1491: #endif
1492: if (mame_debug) {
1493: I(0,testb, DEBUG, D(1), 0);
1494: I(0,jne, LN("z80_mame_debug"),0, 0);
1495: }
1496: }
1497: if (strcmp(op_base, "z_xx")) {
1498: ROP();
1499: } else {
1500: ARG( ECX ); /* byte #4 of [DD/FD CB <ofs8> xx] is read as op_arg! */
1501: }
1502: I(0,jmp, M(4,op_base,0,0,ecx,4),0, "jump to opcode handler");
1503: com(0);
1504: }
1505:
1506: static void mk_debug( void )
1507: {
1508: save_af();
1509: save_z80(0);
1510: #if 0
1511: I(0,movb, AL, zR, "get R");
1512: I(0,andb, AL, X(0x7f), "mask lower seven bits");
1513: I(0,orb, AL, zR2, "get original bit 7");
1514: I(0,movb, zR, AL, "save it for the debugger");
1515: #endif
1516: I(0,call, "_MAME_Debug", 0, 0);
1517: restore_z80();
1518: restore_af();
1519: }
1520:
1521: static void mk_take_irq( int opcode )
1522: {
1523: char symbol[14][32+1];
1524: sprintf(symbol[ 0],"z80_%02x_check_daisy_1", opcode);
1525: sprintf(symbol[ 1],"z80_%02x_check_daisy_2", opcode);
1526: sprintf(symbol[ 2],"z80_%02x_check_daisy_3", opcode);
1527: sprintf(symbol[ 3],"z80_%02x_check_daisy_4", opcode);
1528: sprintf(symbol[ 4],"z80_%02x_check_daisy_5", opcode);
1529: sprintf(symbol[ 5],"z80_%02x_take_irq_1", opcode);
1530: sprintf(symbol[ 6],"z80_%02x_take_irq_2", opcode);
1531: sprintf(symbol[ 7],"z80_%02x_take_irq_3", opcode);
1532: sprintf(symbol[ 8],"z80_%02x_take_irq_4", opcode);
1533: sprintf(symbol[ 9],"z80_%02x_take_irq_5", opcode);
1534: sprintf(symbol[10],"z80_%02x_take_irq_6", opcode);
1535: sprintf(symbol[11],"z80_%02x_take_irq_7", opcode);
1536: sprintf(symbol[12],"z80_%02x_take_irq_8", opcode);
1537: sprintf(symbol[13],"z80_%02x_take_irq_done", opcode);
1538:
1539: I(0,cmpl, irq_max, B(0), "daisy chain mode?");
1540: I(0,je, LN(symbol[ 5]),0, "no, single int");
1541:
1542: #if (!EARLY_CTC)
1543: com("===================================================================");
1544: com(" Z80CTC code ");
1545: com("===================================================================");
1546: save_af();
1547: I(0,movb, zIFF1, D(0), "clear IFF1");
1548: I(0,pushl, D(0), 0, "irqline always 0");
1549: I(0,call, irq_callback, 0, "get the vector");
1550: I(0,addl, ESP, B(4), "clean up stack");
1551: I(0,movzbl, EDX, AL, "EDX = state");
1552: I(0,movl, ECX, EAX, 0);
1553: restore_af();
1554: I(0,shrl, ECX, D(8), "ECX = device");
1555: I(0,cmpl, EDX, int_state(ecx), "state change?");
1556: I(0,je, LN(symbol[ 4]),0, "no change, skip");
1557: I(0,movl, int_state(ecx), EDX, "store new state");
1558: I(0,movl, EDX, D(-1), 0);
1559: I(0,movl, ECX, D(0), 0);
1560: I(0,movl, request_irq, EDX, "reset request IRQ");
1561: I(0,movl, service_irq, EDX, "reset service IRQ");
1562: pad(align_loops);
1563: S(symbol[1],0);
1564: I(0,testl, int_state(ecx), X(Z80_INT_IEO), "Z80_INT_IEO set?");
1565: I(0,je, LS(symbol[2]),0, "no, skip");
1566: I(0,movl, request_irq, EDX, "mask lower IRQ");
1567: I(0,movl, service_irq, ECX, "set service device number");
1568: com(0);
1569: S(symbol[2],0);
1570: I(0,testl, int_state(ecx), X(Z80_INT_REQ), "Z80_INT_REQ set?");
1571: I(0,je, LS(symbol[3]),0, "no, skip");
1572: I(0,movl, request_irq, ECX, "set request device number");
1573: com(0);
1574: S(symbol[3],0);
1575: I(0,incl, ECX, 0, "next device");
1576: I(0,cmpl, ECX, irq_max, "more entries to check?");
1577: I(0,jb, LS(symbol[1]),0, "yes, check them");
1578: #endif
1579: com("===================================================================");
1580: com(" check Z80CTC request irq ");
1581: com("===================================================================");
1582: S(symbol[ 4],0);
1583: I(0,movl, ECX, request_irq, "get device");
1584: I(0,cmpl, ECX, B(0), "request?");
1585: I(0,jl, LN(symbol[13]),0, "should not happen, but...");
1586: save_af();
1587: I(0,lea, ECX, M(0,0,0,0,ecx,4), "* sizeof(Z80_DaisyChain)");
1588: I(0,pushl, irq(ecx,12), 0, "Z80.irq[device].irq_param");
1589: I(0,call, irq(ecx, 4), 0, "call Z80.irq[device].interrupt_entry");
1590: I(0,addl, ESP, B(4), "one DWORD was pushed");
1591: I(0,movl, vector_d, EAX, "store vector");
1592: restore_af();
1593: I(0,movl, request_irq, D(-1), "reset request IRQ");
1594: I(0,jmp, LS(symbol[ 6]), 0, 0);
1595:
1596: com("===================================================================");
1597: com(" single interrupt code ");
1598: com("===================================================================");
1599: S(symbol[ 5],0);
1600: save_af();
1601: I(0,movb, zIFF1, D(0), "clear IFF1");
1602: I(0,pushl, D(0), 0, "irqline always 0");
1603: I(0,call, irq_callback, 0, "do a irq_callback");
1604: I(0,movl, vector_d, EAX, "store vector");
1605: I(0,addl, ESP, B(4), "one DWORD was pushed");
1606: restore_af();
1607:
1608: com("===================================================================");
1609: com(" here when a valid vector is set ");
1610: com("===================================================================");
1611: S(symbol[ 6],0);
1612: com(0);
1613: I(0,cmpb, zHALT, D(1), "CPU was halted?");
1614: I(0,jne, LS(symbol[ 7]), 0, "no, skip");
1615: I(0,movb, zHALT, D(0), "clear halt flag");
1616: I(0,incw, PC, 0, 0);
1617: com(0);
1618: S(symbol[ 7],0);
1619: I(0,movl, PREVPC, D(-1), "no valid previous PC");
1620: I(0,cmpb, zIM, B(2), "interrupt mode 2?");
1621: I(0,jne, LN(symbol[ 8]), 0, "no, test IM 1");
1622: I(0,call, "z80_push_pc", 0, 0);
1623: I(0,movzwl, ECX, vector_w, "get vector");
1624: I(0,movb, CH, zI, "get MSB from I register");
1625: RWORD( 0, PC32, ECX );
1626: I(0,jmp, symbol[12], 0, "change PC and exit");
1627:
1628: com(0);
1629: S(symbol[ 8],0);
1630: I(0,cmpb, zIM, B(1), "interrupt mode 1?");
1631: I(0,jne, LN(symbol[ 9]),0, "no, it's IM 0");
1632: I(0,call, "z80_push_pc", 0, 0);
1633: I(0,addl, zIEXTRN, B(11), "subtract <RST xx> cycles");
1634: I(0,movl, PC32, X(0x38), "<RST 38> vector");
1635: I(0,jmp, symbol[12], 0, "change PC and exit");
1636:
1637: com("===================================================================");
1638: com(" here when interrupt mode is 0 ");
1639: com("===================================================================");
1640: S(symbol[ 9],0);
1641: I(0,cmpb, vector_h, X(0xcd), "opcode <CALL imm16>?");
1642: I(0,jne, LN(symbol[10]),0, "no, skip");
1643: I(0,call, "z80_push_pc", 0, 0);
1644: // The C core doesn't count cycles for <CALL imm16> vector
1645: // I(0,addl, zIEXTRN, B(17), "subtract cycles for CALL opcode");
1646: I(0,movzwl, PC32, vector_w, "get vector bits 0..15");
1647: I(0,jmp, LS(symbol[12]), 0, "change PC and exit");
1648:
1649: com(0);
1650: S(symbol[10],0);
1651: I(0,cmpb, vector_h, X(0xc3), "opcode <JP imm16>?");
1652: I(0,jne, LS(symbol[11]), 0, "no, skip");
1653: // The C core doesn't count cycles for <JP imm16> vector
1654: // I(0,addl, zIEXTRN, B(10), "subtract cycles for JP opcode");
1655: I(0,movzwl, PC32, vector_w, "get vector bits 0..15");
1656: I(0,jmp, LS(symbol[12]), 0, "change PC and exit");
1657:
1658: com(0);
1659: S(symbol[11],0);
1660: com("===================================================================");
1661: com(" here when vector is single byte opcode ");
1662: com("===================================================================");
1663: I(0,call, "z80_push_pc", 0, 0);
1664: I(0,addl, zIEXTRN, B(11), "assume <RST xx> cycles");
1665: I(0,movl, PC32, vector_d, "get vector");
1666: I(0,andl, PC32, B(0x38), "mask RST vector");
1667:
1668: com("===================================================================");
1669: com(" here with new PC ");
1670: com("===================================================================");
1671: S(symbol[12],0);
1672: CHANGE_PC();
1673:
1674: com(0);
1675: pad(align_jumps);
1676: S(symbol[13],0);
1677: save_af();
1678: save_z80(0);
1679: }
1680:
1681: static void mk_header(void)
1682: {
1683: int i;
1684:
1685: com("===========================================================================");
1686: com(" ");
1687: com(" Z80 x86 cpu emulation ");
1688: com(" Copyright (c) 1998 by Juergen Buchmueller ");
1689: com(" ([email protected]) ");
1690: com(" ");
1691: if (as == GAS)
1692: com(" For assembly by GNU assembler only ");
1693: else
1694: if (as == NASM)
1695: com(" For assembly by NASM only ");
1696: else
1697: com(" For assembly by TASM 3.2 and later only ");
1698: com(" ");
1699: com(" Theory of operation ");
1700: com(" eax holds the current accumulator and flags (al = A, ah = F) ");
1701: com(" ecx is used as temporary register (address) ");
1702: com(" edx is used as temporary register (data) ");
1703: com(" esi holds the current program counter (PC) ");
1704: com(" ebp is used as memory handler return address ");
1705: com(" ");
1706: com("===========================================================================");
1707: com(0);
1708: if (as == NASM)
1709: emit("bits\t32");
1710: if (as == TASM)
1711: {
1712: emit(".486");
1713: emit(".model\tflat");
1714: }
1715: com(0);
1716: I(0,data,0,0,0);
1717: S("z_op",0);
1718: I(0,dd,"op_00,op_01,op_02,op_03,op_04,op_05,op_06,op_07,op_08,op_09,op_0a,op_0b,op_0c,op_0d,op_0e,op_0f",0,0);
1719: I(0,dd,"op_10,op_11,op_12,op_13,op_14,op_15,op_16,op_17,op_18,op_19,op_1a,op_1b,op_1c,op_1d,op_1e,op_1f",0,0);
1720: I(0,dd,"op_20,op_21,op_22,op_23,op_24,op_25,op_26,op_27,op_28,op_29,op_2a,op_2b,op_2c,op_2d,op_2e,op_2f",0,0);
1721: I(0,dd,"op_30,op_31,op_32,op_33,op_34,op_35,op_36,op_37,op_38,op_39,op_3a,op_3b,op_3c,op_3d,op_3e,op_3f",0,0);
1722: I(0,dd,"op_40,op_41,op_42,op_43,op_44,op_45,op_46,op_47,op_48,op_49,op_4a,op_4b,op_4c,op_4d,op_4e,op_4f",0,0);
1723: I(0,dd,"op_50,op_51,op_52,op_53,op_54,op_55,op_56,op_57,op_58,op_59,op_5a,op_5b,op_5c,op_5d,op_5e,op_5f",0,0);
1724: I(0,dd,"op_60,op_61,op_62,op_63,op_64,op_65,op_66,op_67,op_68,op_69,op_6a,op_6b,op_6c,op_6d,op_6e,op_6f",0,0);
1725: I(0,dd,"op_70,op_71,op_72,op_73,op_74,op_75,op_76,op_77,op_78,op_79,op_7a,op_7b,op_7c,op_7d,op_7e,op_7f",0,0);
1726: I(0,dd,"op_80,op_81,op_82,op_83,op_84,op_85,op_86,op_87,op_88,op_89,op_8a,op_8b,op_8c,op_8d,op_8e,op_8f",0,0);
1727: I(0,dd,"op_90,op_91,op_92,op_93,op_94,op_95,op_96,op_97,op_98,op_99,op_9a,op_9b,op_9c,op_9d,op_9e,op_9f",0,0);
1728: I(0,dd,"op_a0,op_a1,op_a2,op_a3,op_a4,op_a5,op_a6,op_a7,op_a8,op_a9,op_aa,op_ab,op_ac,op_ad,op_ae,op_af",0,0);
1729: I(0,dd,"op_b0,op_b1,op_b2,op_b3,op_b4,op_b5,op_b6,op_b7,op_b8,op_b9,op_ba,op_bb,op_bc,op_bd,op_be,op_bf",0,0);
1730: I(0,dd,"op_c0,op_c1,op_c2,op_c3,op_c4,op_c5,op_c6,op_c7,op_c8,op_c9,op_ca,op_cb,op_cc,op_cd,op_ce,op_cf",0,0);
1731: I(0,dd,"op_d0,op_d1,op_d2,op_d3,op_d4,op_d5,op_d6,op_d7,op_d8,op_d9,op_da,op_db,op_dc,op_dd,op_de,op_df",0,0);
1732: I(0,dd,"op_e0,op_e1,op_e2,op_e3,op_e4,op_e5,op_e6,op_e7,op_e8,op_e9,op_ea,op_eb,op_ec,op_ed,op_ee,op_ef",0,0);
1733: I(0,dd,"op_f0,op_f1,op_f2,op_f3,op_f4,op_f5,op_f6,op_f7,op_f8,op_f9,op_fa,op_fb,op_fc,op_fd,op_fe,op_ff",0,0);
1734: com(0);
1735: S("z_cb",0);
1736: I(0,dd,"cb_00,cb_01,cb_02,cb_03,cb_04,cb_05,cb_06,cb_07,cb_08,cb_09,cb_0a,cb_0b,cb_0c,cb_0d,cb_0e,cb_0f",0,0);
1737: I(0,dd,"cb_10,cb_11,cb_12,cb_13,cb_14,cb_15,cb_16,cb_17,cb_18,cb_19,cb_1a,cb_1b,cb_1c,cb_1d,cb_1e,cb_1f",0,0);
1738: I(0,dd,"cb_20,cb_21,cb_22,cb_23,cb_24,cb_25,cb_26,cb_27,cb_28,cb_29,cb_2a,cb_2b,cb_2c,cb_2d,cb_2e,cb_2f",0,0);
1739: I(0,dd,"cb_30,cb_31,cb_32,cb_33,cb_34,cb_35,cb_36,cb_37,cb_38,cb_39,cb_3a,cb_3b,cb_3c,cb_3d,cb_3e,cb_3f",0,0);
1740: I(0,dd,"cb_40,cb_41,cb_42,cb_43,cb_44,cb_45,cb_46,cb_47,cb_48,cb_49,cb_4a,cb_4b,cb_4c,cb_4d,cb_4e,cb_4f",0,0);
1741: I(0,dd,"cb_50,cb_51,cb_52,cb_53,cb_54,cb_55,cb_56,cb_57,cb_58,cb_59,cb_5a,cb_5b,cb_5c,cb_5d,cb_5e,cb_5f",0,0);
1742: I(0,dd,"cb_60,cb_61,cb_62,cb_63,cb_64,cb_65,cb_66,cb_67,cb_68,cb_69,cb_6a,cb_6b,cb_6c,cb_6d,cb_6e,cb_6f",0,0);
1743: I(0,dd,"cb_70,cb_71,cb_72,cb_73,cb_74,cb_75,cb_76,cb_77,cb_78,cb_79,cb_7a,cb_7b,cb_7c,cb_7d,cb_7e,cb_7f",0,0);
1744: I(0,dd,"cb_80,cb_81,cb_82,cb_83,cb_84,cb_85,cb_86,cb_87,cb_88,cb_89,cb_8a,cb_8b,cb_8c,cb_8d,cb_8e,cb_8f",0,0);
1745: I(0,dd,"cb_90,cb_91,cb_92,cb_93,cb_94,cb_95,cb_96,cb_97,cb_98,cb_99,cb_9a,cb_9b,cb_9c,cb_9d,cb_9e,cb_9f",0,0);
1746: I(0,dd,"cb_a0,cb_a1,cb_a2,cb_a3,cb_a4,cb_a5,cb_a6,cb_a7,cb_a8,cb_a9,cb_aa,cb_ab,cb_ac,cb_ad,cb_ae,cb_af",0,0);
1747: I(0,dd,"cb_b0,cb_b1,cb_b2,cb_b3,cb_b4,cb_b5,cb_b6,cb_b7,cb_b8,cb_b9,cb_ba,cb_bb,cb_bc,cb_bd,cb_be,cb_bf",0,0);
1748: I(0,dd,"cb_c0,cb_c1,cb_c2,cb_c3,cb_c4,cb_c5,cb_c6,cb_c7,cb_c8,cb_c9,cb_ca,cb_cb,cb_cc,cb_cd,cb_ce,cb_cf",0,0);
1749: I(0,dd,"cb_d0,cb_d1,cb_d2,cb_d3,cb_d4,cb_d5,cb_d6,cb_d7,cb_d8,cb_d9,cb_da,cb_db,cb_dc,cb_dd,cb_de,cb_df",0,0);
1750: I(0,dd,"cb_e0,cb_e1,cb_e2,cb_e3,cb_e4,cb_e5,cb_e6,cb_e7,cb_e8,cb_e9,cb_ea,cb_eb,cb_ec,cb_ed,cb_ee,cb_ef",0,0);
1751: I(0,dd,"cb_f0,cb_f1,cb_f2,cb_f3,cb_f4,cb_f5,cb_f6,cb_f7,cb_f8,cb_f9,cb_fa,cb_fb,cb_fc,cb_fd,cb_fe,cb_ff",0,0);
1752: com(0);
1753: S("z_dd",0);
1754: I(0,dd,"dd_00,dd_01,dd_02,dd_03,dd_04,dd_05,dd_06,dd_07,dd_08,dd_09,dd_0a,dd_0b,dd_0c,dd_0d,dd_0e,dd_0f",0,0);
1755: I(0,dd,"dd_10,dd_11,dd_12,dd_13,dd_14,dd_15,dd_16,dd_17,dd_18,dd_19,dd_1a,dd_1b,dd_1c,dd_1d,dd_1e,dd_1f",0,0);
1756: I(0,dd,"dd_20,dd_21,dd_22,dd_23,dd_24,dd_25,dd_26,dd_27,dd_28,dd_29,dd_2a,dd_2b,dd_2c,dd_2d,dd_2e,dd_2f",0,0);
1757: I(0,dd,"dd_30,dd_31,dd_32,dd_33,dd_34,dd_35,dd_36,dd_37,dd_38,dd_39,dd_3a,dd_3b,dd_3c,dd_3d,dd_3e,dd_3f",0,0);
1758: I(0,dd,"dd_40,dd_41,dd_42,dd_43,dd_44,dd_45,dd_46,dd_47,dd_48,dd_49,dd_4a,dd_4b,dd_4c,dd_4d,dd_4e,dd_4f",0,0);
1759: I(0,dd,"dd_50,dd_51,dd_52,dd_53,dd_54,dd_55,dd_56,dd_57,dd_58,dd_59,dd_5a,dd_5b,dd_5c,dd_5d,dd_5e,dd_5f",0,0);
1760: I(0,dd,"dd_60,dd_61,dd_62,dd_63,dd_64,dd_65,dd_66,dd_67,dd_68,dd_69,dd_6a,dd_6b,dd_6c,dd_6d,dd_6e,dd_6f",0,0);
1761: I(0,dd,"dd_70,dd_71,dd_72,dd_73,dd_74,dd_75,dd_76,dd_77,dd_78,dd_79,dd_7a,dd_7b,dd_7c,dd_7d,dd_7e,dd_7f",0,0);
1762: I(0,dd,"dd_80,dd_81,dd_82,dd_83,dd_84,dd_85,dd_86,dd_87,dd_88,dd_89,dd_8a,dd_8b,dd_8c,dd_8d,dd_8e,dd_8f",0,0);
1763: I(0,dd,"dd_90,dd_91,dd_92,dd_93,dd_94,dd_95,dd_96,dd_97,dd_98,dd_99,dd_9a,dd_9b,dd_9c,dd_9d,dd_9e,dd_9f",0,0);
1764: I(0,dd,"dd_a0,dd_a1,dd_a2,dd_a3,dd_a4,dd_a5,dd_a6,dd_a7,dd_a8,dd_a9,dd_aa,dd_ab,dd_ac,dd_ad,dd_ae,dd_af",0,0);
1765: I(0,dd,"dd_b0,dd_b1,dd_b2,dd_b3,dd_b4,dd_b5,dd_b6,dd_b7,dd_b8,dd_b9,dd_ba,dd_bb,dd_bc,dd_bd,dd_be,dd_bf",0,0);
1766: I(0,dd,"dd_c0,dd_c1,dd_c2,dd_c3,dd_c4,dd_c5,dd_c6,dd_c7,dd_c8,dd_c9,dd_ca,dd_cb,dd_cc,dd_cd,dd_ce,dd_cf",0,0);
1767: I(0,dd,"dd_d0,dd_d1,dd_d2,dd_d3,dd_d4,dd_d5,dd_d6,dd_d7,dd_d8,dd_d9,dd_da,dd_db,dd_dc,dd_dd,dd_de,dd_df",0,0);
1768: I(0,dd,"dd_e0,dd_e1,dd_e2,dd_e3,dd_e4,dd_e5,dd_e6,dd_e7,dd_e8,dd_e9,dd_ea,dd_eb,dd_ec,dd_ed,dd_ee,dd_ef",0,0);
1769: I(0,dd,"dd_f0,dd_f1,dd_f2,dd_f3,dd_f4,dd_f5,dd_f6,dd_f7,dd_f8,dd_f9,dd_fa,dd_fb,dd_fc,dd_fd,dd_fe,dd_ff",0,0);
1770: com(0);
1771: S("z_ed",0);
1772: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1773: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1774: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1775: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1776: I(0,dd,"ed_40,ed_41,ed_42,ed_43,ed_44,ed_45,ed_46,ed_47,ed_48,ed_49,ed_4a,ed_4b,ed_4c,ed_4d,ed_4e,ed_4f",0,0);
1777: I(0,dd,"ed_50,ed_51,ed_52,ed_53,ed_54,ed_55,ed_56,ed_57,ed_58,ed_59,ed_5a,ed_5b,ed_5c,ed_5d,ed_5e,ed_5f",0,0);
1778: I(0,dd,"ed_60,ed_61,ed_62,ed_63,ed_64,ed_65,ed_66,ed_67,ed_68,ed_69,ed_6a,ed_6b,ed_6c,ed_6d,ed_6e,ed_6f",0,0);
1779: I(0,dd,"ed_70,ed_71,ed_72,ed_73,ed_74,ed_75,ed_76,illop,ed_78,ed_79,ed_7a,ed_7b,ed_7c,ed_7d,ed_7e,illop",0,0);
1780: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1781: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1782: I(0,dd,"ed_a0,ed_a1,ed_a2,ed_a3,illop,illop,illop,illop,ed_a8,ed_a9,ed_aa,ed_ab,illop,illop,illop,illop",0,0);
1783: I(0,dd,"ed_b0,ed_b1,ed_b2,ed_b3,illop,illop,illop,illop,ed_b8,ed_b9,ed_ba,ed_bb,illop,illop,illop,illop",0,0);
1784: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1785: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1786: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1787: I(0,dd,"illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop,illop",0,0);
1788: com(0);
1789: S("z_fd",0);
1790: I(0,dd,"fd_00,fd_01,fd_02,fd_03,fd_04,fd_05,fd_06,fd_07,fd_08,fd_09,fd_0a,fd_0b,fd_0c,fd_0d,fd_0e,fd_0f",0,0);
1791: I(0,dd,"fd_10,fd_11,fd_12,fd_13,fd_14,fd_15,fd_16,fd_17,fd_18,fd_19,fd_1a,fd_1b,fd_1c,fd_1d,fd_1e,fd_1f",0,0);
1792: I(0,dd,"fd_20,fd_21,fd_22,fd_23,fd_24,fd_25,fd_26,fd_27,fd_28,fd_29,fd_2a,fd_2b,fd_2c,fd_2d,fd_2e,fd_2f",0,0);
1793: I(0,dd,"fd_30,fd_31,fd_32,fd_33,fd_34,fd_35,fd_36,fd_37,fd_38,fd_39,fd_3a,fd_3b,fd_3c,fd_3d,fd_3e,fd_3f",0,0);
1794: I(0,dd,"fd_40,fd_41,fd_42,fd_43,fd_44,fd_45,fd_46,fd_47,fd_48,fd_49,fd_4a,fd_4b,fd_4c,fd_4d,fd_4e,fd_4f",0,0);
1795: I(0,dd,"fd_50,fd_51,fd_52,fd_53,fd_54,fd_55,fd_56,fd_57,fd_58,fd_59,fd_5a,fd_5b,fd_5c,fd_5d,fd_5e,fd_5f",0,0);
1796: I(0,dd,"fd_60,fd_61,fd_62,fd_63,fd_64,fd_65,fd_66,fd_67,fd_68,fd_69,fd_6a,fd_6b,fd_6c,fd_6d,fd_6e,fd_6f",0,0);
1797: I(0,dd,"fd_70,fd_71,fd_72,fd_73,fd_74,fd_75,fd_76,fd_77,fd_78,fd_79,fd_7a,fd_7b,fd_7c,fd_7d,fd_7e,fd_7f",0,0);
1798: I(0,dd,"fd_80,fd_81,fd_82,fd_83,fd_84,fd_85,fd_86,fd_87,fd_88,fd_89,fd_8a,fd_8b,fd_8c,fd_8d,fd_8e,fd_8f",0,0);
1799: I(0,dd,"fd_90,fd_91,fd_92,fd_93,fd_94,fd_95,fd_96,fd_97,fd_98,fd_99,fd_9a,fd_9b,fd_9c,fd_9d,fd_9e,fd_9f",0,0);
1800: I(0,dd,"fd_a0,fd_a1,fd_a2,fd_a3,fd_a4,fd_a5,fd_a6,fd_a7,fd_a8,fd_a9,fd_aa,fd_ab,fd_ac,fd_ad,fd_ae,fd_af",0,0);
1801: I(0,dd,"fd_b0,fd_b1,fd_b2,fd_b3,fd_b4,fd_b5,fd_b6,fd_b7,fd_b8,fd_b9,fd_ba,fd_bb,fd_bc,fd_bd,fd_be,fd_bf",0,0);
1802: I(0,dd,"fd_c0,fd_c1,fd_c2,fd_c3,fd_c4,fd_c5,fd_c6,fd_c7,fd_c8,fd_c9,fd_ca,fd_cb,fd_cc,fd_cd,fd_ce,fd_cf",0,0);
1803: I(0,dd,"fd_d0,fd_d1,fd_d2,fd_d3,fd_d4,fd_d5,fd_d6,fd_d7,fd_d8,fd_d9,fd_da,fd_db,fd_dc,fd_dd,fd_de,fd_df",0,0);
1804: I(0,dd,"fd_e0,fd_e1,fd_e2,fd_e3,fd_e4,fd_e5,fd_e6,fd_e7,fd_e8,fd_e9,fd_ea,fd_eb,fd_ec,fd_ed,fd_ee,fd_ef",0,0);
1805: I(0,dd,"fd_f0,fd_f1,fd_f2,fd_f3,fd_f4,fd_f5,fd_f6,fd_f7,fd_f8,fd_f9,fd_fa,fd_fb,fd_fc,fd_fd,fd_fe,fd_ff",0,0);
1806: com(0);
1807: S("z_xx",0);
1808: I(0,dd,"xx_00,xx_01,xx_02,xx_03,xx_04,xx_05,xx_06,xx_07,xx_08,xx_09,xx_0a,xx_0b,xx_0c,xx_0d,xx_0e,xx_0f",0,0);
1809: I(0,dd,"xx_10,xx_11,xx_12,xx_13,xx_14,xx_15,xx_16,xx_17,xx_18,xx_19,xx_1a,xx_1b,xx_1c,xx_1d,xx_1e,xx_1f",0,0);
1810: I(0,dd,"xx_20,xx_21,xx_22,xx_23,xx_24,xx_25,xx_26,xx_27,xx_28,xx_29,xx_2a,xx_2b,xx_2c,xx_2d,xx_2e,xx_2f",0,0);
1811: I(0,dd,"xx_30,xx_31,xx_32,xx_33,xx_34,xx_35,xx_36,xx_37,xx_38,xx_39,xx_3a,xx_3b,xx_3c,xx_3d,xx_3e,xx_3f",0,0);
1812: I(0,dd,"xx_40,xx_41,xx_42,xx_43,xx_44,xx_45,xx_46,xx_47,xx_48,xx_49,xx_4a,xx_4b,xx_4c,xx_4d,xx_4e,xx_4f",0,0);
1813: I(0,dd,"xx_50,xx_51,xx_52,xx_53,xx_54,xx_55,xx_56,xx_57,xx_58,xx_59,xx_5a,xx_5b,xx_5c,xx_5d,xx_5e,xx_5f",0,0);
1814: I(0,dd,"xx_60,xx_61,xx_62,xx_63,xx_64,xx_65,xx_66,xx_67,xx_68,xx_69,xx_6a,xx_6b,xx_6c,xx_6d,xx_6e,xx_6f",0,0);
1815: I(0,dd,"xx_70,xx_71,xx_72,xx_73,xx_74,xx_75,xx_76,xx_77,xx_78,xx_79,xx_7a,xx_7b,xx_7c,xx_7d,xx_7e,xx_7f",0,0);
1816: I(0,dd,"xx_80,xx_81,xx_82,xx_83,xx_84,xx_85,xx_86,xx_87,xx_88,xx_89,xx_8a,xx_8b,xx_8c,xx_8d,xx_8e,xx_8f",0,0);
1817: I(0,dd,"xx_90,xx_91,xx_92,xx_93,xx_94,xx_95,xx_96,xx_97,xx_98,xx_99,xx_9a,xx_9b,xx_9c,xx_9d,xx_9e,xx_9f",0,0);
1818: I(0,dd,"xx_a0,xx_a1,xx_a2,xx_a3,xx_a4,xx_a5,xx_a6,xx_a7,xx_a8,xx_a9,xx_aa,xx_ab,xx_ac,xx_ad,xx_ae,xx_af",0,0);
1819: I(0,dd,"xx_b0,xx_b1,xx_b2,xx_b3,xx_b4,xx_b5,xx_b6,xx_b7,xx_b8,xx_b9,xx_ba,xx_bb,xx_bc,xx_bd,xx_be,xx_bf",0,0);
1820: I(0,dd,"xx_c0,xx_c1,xx_c2,xx_c3,xx_c4,xx_c5,xx_c6,xx_c7,xx_c8,xx_c9,xx_ca,xx_cb,xx_cc,xx_cd,xx_ce,xx_cf",0,0);
1821: I(0,dd,"xx_d0,xx_d1,xx_d2,xx_d3,xx_d4,xx_d5,xx_d6,xx_d7,xx_d8,xx_d9,xx_da,xx_db,xx_dc,xx_dd,xx_de,xx_df",0,0);
1822: I(0,dd,"xx_e0,xx_e1,xx_e2,xx_e3,xx_e4,xx_e5,xx_e6,xx_e7,xx_e8,xx_e9,xx_ea,xx_eb,xx_ec,xx_ed,xx_ee,xx_ef",0,0);
1823: I(0,dd,"xx_f0,xx_f1,xx_f2,xx_f3,xx_f4,xx_f5,xx_f6,xx_f7,xx_f8,xx_f9,xx_fa,xx_fb,xx_fc,xx_fd,xx_fe,xx_ff",0,0);
1824: com(0);
1825: com(0);
1826: S("z80_daa",0);
1827: for (i = 0; i < sizeof(DAATable)/sizeof(DAATable[0]); i += 4) {
1828: char buffer[32+1];
1829: sprintf(buffer,"%5d,%5d,%5d,%5d",
1830: (word)((DAATable[i+0]<<8)|(DAATable[i+0]>>8)),
1831: (word)((DAATable[i+1]<<8)|(DAATable[i+1]>>8)),
1832: (word)((DAATable[i+2]<<8)|(DAATable[i+2]>>8)),
1833: (word)((DAATable[i+3]<<8)|(DAATable[i+3]>>8)));
1834: I(0,dw,buffer,0,0);
1835: }
1836: I(0,globl,"_Z80_ICount",0,0);
1837: I("_Z80_ICount",dd,"0",0,"cycle count during run");
1838: I("z80_itotal",dd,"0",0,"total cycles to run");
1839: I("z80_iextrn",dd,"0",0,"external cycles to subtract (interrupt)");
1840: com(0);
1841: I(0,globl,"_Z80",0,0);
1842: S("_Z80",0);
1843: I("z80_AF", dd,"0",0,"offset _Z80 + 0x00");
1844: I("z80_BC", dd,"0",0,"offset _Z80 + 0x04");
1845: I("z80_DE", dd,"0",0,"offset _Z80 + 0x08");
1846: I("z80_HL", dd,"0",0,"offset _Z80 + 0x0c");
1847: I("z80_IX", dd,"0",0,"offset _Z80 + 0x10");
1848: I("z80_IY", dd,"0",0,"offset _Z80 + 0x14");
1849: I("z80_PC", dd,"0",0,"offset _Z80 + 0x18");
1850: I("z80_SP", dd,"0",0,"offset _Z80 + 0x1c");
1851: I("z80_AF2", dd,"0",0,"offset _Z80 + 0x20");
1852: I("z80_BC2", dd,"0",0,"offset _Z80 + 0x24");
1853: I("z80_DE2", dd,"0",0,"offset _Z80 + 0x28");
1854: I("z80_HL2", dd,"0",0,"offset _Z80 + 0x2c");
1855: I("z80_R", db,"0",0,"offset _Z80 + 0x30");
1856: I("z80_R2", db,"0",0,"offset _Z80 + 0x31");
1857: I("z80_IFF1", db,"0",0,"offset _Z80 + 0x32");
1858: I("z80_IFF2", db,"0",0,"offset _Z80 + 0x33");
1859: I("z80_HALT", db,"0",0,"offset _Z80 + 0x34");
1860: I("z80_IM", db,"0",0,"offset _Z80 + 0x35");
1861: I("z80_I", db,"0",0,"offset _Z80 + 0x36");
1862: I("z80_pending_irq",db,"0",0,"offset _Z80 + 0x37");
1863: I("z80_vector", dd,"0",0,"offset _Z80 + 0x38");
1864: I("z80_irq_max", dd,"0",0,"offset _Z80 + 0x3c");
1865: I("z80_request_irq",dd,"0",0,"offset _Z80 + 0x40");
1866: I("z80_service_irq",dd,"0",0,"offset _Z80 + 0x44");
1867: I("z80_int_state", dd,"0,0,0,0",0,"offset _Z80 + 0x48");
1868: I("z80_irq", dd,"0,0,0,0",0,"offset _Z80 + 0x58");
1869: I(0, dd,"0,0,0,0",0,"offset _Z80 + 0x68");
1870: I(0, dd,"0,0,0,0",0,"offset _Z80 + 0x78");
1871: I(0, dd,"0,0,0,0",0,"offset _Z80 + 0x88");
1872: I("z80_nmi_state", dd,"0",0,"offset _Z80 + 0x98");
1873: I("z80_irq_state", dd,"0",0,"offset _Z80 + 0x9c");
1874: I("z80_irq_callback",dd,"0",0,"offset _Z80 + 0xa0");
1875: #define Z80_SIZE 0x00a4
1876:
1877: I("z80_EA", dd,"0",0,"temporary storage for effective address");
1878: I("z80_MB", dd,"0",0,"temporary storage for memory byte (LSB or MSB)");
1879: com(0);
1880: if (mame_debug)
1881: I(0,extrn,"_mame_debug",0,0);
1882: if (verbose)
1883: I(0,extrn,"_errorlog",0,0);
1884: I(0,extrn,"_previouspc",0,0);
1885: I(0,extrn,"_ROM",0,0);
1886: I(0,extrn,"_RAM",0,0);
1887: I(0,extrn,"_OP_ROM",0,0);
1888: I(0,extrn,"_OP_RAM",0,0);
1889: com(0);
1890: I(0,text,0,0,0);
1891: I(0,extrn,"_malloc",0,0);
1892: I(0,extrn,"_raise",0,0);
1893: if (mame_debug)
1894: I(0,extrn,"_MAME_Debug",0,0);
1895: if (verbose)
1896: I(0,extrn,"_fprintf",0,0);
1897: com(0);
1898: I(0,extrn,"_ophw",0,0);
1899: I(0,extrn,"_cpu_bankbase",0,0);
1900: com(0);
1901: I(0,extrn,"_mrh_error",0,0);
1902: I(0,extrn,"_cur_mrhard",0,0);
1903: I(0,extrn,"_readhardware",0,0);
1904: I(0,extrn,"_memoryreadoffset",0,0);
1905: I(0,extrn,"_memoryreadhandler",0,0);
1906: I(0,extrn,"_cur_mwhard",0,0);
1907: com(0);
1908: I(0,extrn,"_mwh_error",0,0);
1909: I(0,extrn,"_writehardware",0,0);
1910: I(0,extrn,"_memorywriteoffset",0,0);
1911: I(0,extrn,"_memorywritehandler",0,0);
1912: I(0,extrn,"_cpu_setOPbase16",0,0);
1913: I(0,extrn,"_cpu_getactivecpu",0,0);
1914: com(0);
1915: I(0,extrn,"_cpu_readmem16",0,0);
1916: I(0,extrn,"_cpu_writemem16",0,0);
1917: #if INLINE_IOPORTS
1918: I(0,extrn,"_cur_portmask",0,0);
1919: I(0,extrn,"_cur_readport",0,0);
1920: I(0,extrn,"_cur_writeport",0,0);
1921: #else
1922: I(0,extrn,"_cpu_readport",0,0);
1923: I(0,extrn,"_cpu_writeport",0,0);
1924: #endif
1925: com(0);
1926: }
1927:
1928: static void mk_interface(void)
1929: {
1930: I(0,text,0,0,0);
1931: pad(align_funcs);
1932: com("===================================================================");
1933: com(" void Z80_SetRegs(void *regs); ");
1934: com("===================================================================");
1935: I(0,globl,"_Z80_SetRegs",0,0);
1936: S("_Z80_SetRegs",0);
1937: I(0,pushl, ESI, 0, 0);
1938: I(0,pushl, EDI, 0, 0);
1939: I(0,movl, ESI, M(4,0,esp,12,0,0), "get source");
1940: debug(7,"Z80_SetRegs(0x%08x)\n",ESI);
1941: I(0,movl, EDI, O("_Z80"), "set destination");
1942: I(0,movl, ECX, X(Z80_SIZE/4), 0);
1943: I(0,cld, 0, 0, 0);
1944: I(0,rep, 0, 0, 0);
1945: I(0,movsd, 0, 0, 0);
1946: I(0,movl, ECX, zPC32, 0);
1947: I(0,movl, EDI, MRHARD, 0);
1948: I(0,shrl, ECX, D(ABITS), 0);
1949: I(0,movb, CL, M(1,0,edi,0,ecx,1), 0);
1950: I(0,cmpb, CL, M(1,"_ophw",0,0,0,0),0);
1951: I(0,je, "z80_set_context_1",0, 0);
1952: I(0,pushl, zPC32, 0, 0);
1953: I(0,call, "_cpu_setOPbase16",0, 0);
1954: I(0,addl, ESP, B(4), 0);
1955: S("z80_set_context_1",0);
1956: dumpregs();
1957: I(0,popl, EDI, 0, 0);
1958: I(0,popl, ESI, 0, 0);
1959: I(0,ret, 0, 0, 0);
1960:
1961: pad(align_funcs);
1962: com("===================================================================");
1963: com(" void Z80_GetRegs(void *regs); ");
1964: com("===================================================================");
1965: I(0,globl,"_Z80_GetRegs",0,0);
1966: S("_Z80_GetRegs",0);
1967: I(0,pushl, ESI, 0, 0);
1968: I(0,pushl, EDI, 0, 0);
1969: I(0,movl, EDI, M(4,0,esp,12,0,0), "get destination");
1970: debug(7,"Z80_GetRegs(0x%08x)\n",EDI);
1971: I(0,movl, ESI, O("_Z80"), "set source");
1972: I(0,movl, ECX, X(Z80_SIZE/4), 0);
1973: I(0,cld, 0, 0, 0);
1974: I(0,rep, 0, 0, 0);
1975: I(0,movsd, 0, 0, 0);
1976: dumpregs();
1977: I(0,popl, EDI, 0, 0);
1978: I(0,popl, ESI, 0, 0);
1979: I(0,ret, 0, 0, 0);
1980:
1981: pad(align_funcs);
1982: com("===================================================================");
1983: com(" unsigned Z80_GetPC(void); ");
1984: com("===================================================================");
1985: I(0,globl,"_Z80_GetPC",0,0);
1986: S("_Z80_GetPC",0);
1987: I(0,movl, EAX, zPC32, 0);
1988: debug(7,"Z80_GetPC() %04x\n",EAX);
1989: I(0,ret, 0, 0, 0);
1990:
1991: pad(align_funcs);
1992: com("===================================================================");
1993: com(" void Z80_set_nmi_line(int state); ");
1994: com("===================================================================");
1995: I(0,globl,"_Z80_set_nmi_line",0,0);
1996: S("_Z80_set_nmi_line",0);
1997: I(0,pushl, EBP, 0, 0);
1998: I(0,pushl, EBX, 0, 0);
1999: I(0,pushl, ESI, 0, 0);
2000: I(0,pushl, EDI, 0, 0);
2001: I(0,movl, ECX, M(4,0,esp,20,0,0), "get state");
2002: debug(3,"Z80_set_nmi_line(%d)\n",ECX);
2003: I(0,cmpl, ECX, nmi_state, "changed?");
2004: I(0,je, LN("z80_set_nmi_line_done"),0, "no, leave");
2005: I(0,movl, nmi_state, ECX, "store new state");
2006: I(0,cmpl, ECX, B(CLEAR_LINE), "clear line now?");
2007: I(0,je, LN("z80_set_nmi_line_done"),0, "yes, skip");
2008: com(0);
2009: restore_z80();
2010: restore_af();
2011: I(0,movl, PREVPC, D(-1), "no valid previous PC");
2012: I(0,testb, zHALT, D(1), "halted?");
2013: I(0,je, LS("z80_set_nmi_line_1"),0, "no, skip");
2014: I(0,movb, zHALT, D(0), "clear halt flag");
2015: I(0,incw, PC, 0, 0);
2016: com(0);
2017: S("z80_set_nmi_line_1",0);
2018: I(0,call, "z80_push_pc", 0, 0);
2019: I(0,movb, CL, X(0x00), 0);
2020: I(0,xchgb, CL, zIFF1, "clear IFF1 and copy");
2021: I(0,movb, zIFF2, CL, "previous state to IFF2");
2022: I(0,movl, PC32, X(0x66), "PC = NMI vector");
2023: I(0,movl, ECX, PC32, 0);
2024: I(0,movl, EDI, MRHARD, 0);
2025: I(0,shrl, ECX, D(ABITS), 0);
2026: I(0,movb, CL, M(1,0,edi,0,ecx,1), 0);
2027: I(0,cmpb, CL, M(1,"_ophw",0,0,0,0), 0);
2028: I(0,je, LS("z80_set_nmi_line_2"),0, 0);
2029: I(0,pushl, zPC32, 0, 0);
2030: I(0,call, "_cpu_setOPbase16",0, 0);
2031: I(0,addl, ESP, B(4), 0);
2032: S("z80_set_nmi_line_2",0);
2033: save_af();
2034: save_z80(0);
2035: com(0);
2036: S("z80_set_nmi_line_done",0);
2037: I(0,popl, EDI, 0, 0);
2038: I(0,popl, ESI, 0, 0);
2039: I(0,popl, EBX, 0, 0);
2040: I(0,popl, EBP, 0, 0);
2041: I(0,ret, 0, 0, 0);
2042:
2043: pad(align_funcs);
2044: com("===================================================================");
2045: com(" void Z80_set_irq_line(int irqline, int state); ");
2046: com("===================================================================");
2047: I(0,globl,"_Z80_set_irq_line",0,0);
2048: S("_Z80_set_irq_line",0);
2049: I(0,pushl, EBP, 0, 0);
2050: I(0,pushl, EBX, 0, 0);
2051: I(0,pushl, ESI, 0, 0);
2052: I(0,pushl, EDI, 0, 0);
2053: restore_af();
2054: restore_z80();
2055: I(0,movl, EDX, M(4,0,esp,24,0,0), 0);
2056: I(0,movl, ECX, M(4,0,esp,20,0,0), 0);
2057: I(0,movl, irq_state, EDX, 0);
2058: debug(3,"Z80_set_irq_line(%d,%d)\n",ECX,EDX);
2059: I(0,cmpl, EDX, B(CLEAR_LINE), "line cleared?");
2060: I(0,je, LN("z80_set_irq_line_done"),0, "yes, leave");
2061: #if EARLY_CTC
2062: I(0,cmpl, irq_max, B(0), "daisy chain mode?");
2063: I(0,je, LN("z80_set_irq_line_assert"),0, "no, it's single int");
2064: save_af();
2065: I(0,pushl, D(0), 0, "irqline always 0");
2066: I(0,call, irq_callback, 0, "get the vector");
2067: I(0,addl, ESP, B(4), "clean up stack");
2068: I(0,movl, ECX, EAX, "ECX = (device<<8)");
2069: I(0,movzbl, EDX, AL, "EDX = state");
2070: restore_af();
2071: I(0,shrl, ECX, D(8), "ECX = device");
2072: I(0,cmpl, EDX, int_state(ecx), "state change?");
2073: I(0,je, LN("z80_set_irq_line_assert"),0, "no change, skip");
2074: I(0,movl, int_state(ecx), EDX, "store new state");
2075: I(0,movl, EDX, D(-1), 0);
2076: I(0,movl, ECX, D(0), 0);
2077: I(0,movl, request_irq, EDX, "reset request IRQ");
2078: I(0,movl, service_irq, EDX, "reset service IRQ");
2079: S("z80_set_irq_line_dc_1",0);
2080: I(0,testl, int_state(ecx), X(Z80_INT_IEO), "Z80_INT_IEO set?");
2081: I(0,je, LS("z80_set_irq_line_dc_2"),0, "no, skip");
2082: I(0,movl, request_irq, EDX, "mask lower IRQ");
2083: I(0,movl, service_irq, ECX, "set service device number");
2084: com(0);
2085: S("z80_set_irq_line_dc_2",0);
2086: I(0,testb, int_state(ecx), X(Z80_INT_REQ), "Z80_INT_REQ set?");
2087: I(0,je, LS("z80_set_irq_line_dc_3"),0, "no, skip");
2088: I(0,movl, request_irq, ECX, "set request device number");
2089: com(0);
2090: S("z80_set_irq_line_dc_3",0);
2091: I(0,incl, ECX, 0, "next device");
2092: I(0,cmpl, ECX, irq_max, "more entries to check?");
2093: I(0,jb, LS("z80_set_irq_line_dc_1"),0, "yes, check them");
2094: S("z80_set_irq_line_assert",0);
2095: #endif
2096: I(0,testb, zIFF1, X(INT_IRQ), "interrupts enabled?");
2097: I(0,je, LN("z80_set_irq_line_done"),0, "no, leave");
2098: mk_take_irq( 0x00 );
2099: S("z80_set_irq_line_done",0);
2100: save_af();
2101: save_z80(0);
2102: I(0,popl, EDI, 0, 0);
2103: I(0,popl, ESI, 0, 0);
2104: I(0,popl, EBX, 0, 0);
2105: I(0,popl, EBP, 0, 0);
2106: I(0,ret, 0, 0, 0);
2107: com(0);
2108:
2109: pad(align_funcs);
2110: com("===================================================================");
2111: com(" void Z80_set_irq_callback(int (*callback)(int irqline)); ");
2112: com("===================================================================");
2113: I(0,globl,"_Z80_set_irq_callback",0,0);
2114: S("_Z80_set_irq_callback",0);
2115: I(0,movl, EAX, M(4,0,esp,4,0,0), 0);
2116: debug(3,"Z80_set_irq_callback(%x)\n",EAX);
2117: I(0,movl, irq_callback, EAX, 0);
2118: I(0,ret,0,0,0);
2119: com(0);
2120:
2121: pad(align_funcs);
2122: com("===================================================================");
2123: com(" void Z80_Reset(Z80_DaisyChain *daisy_chain); ");
2124: com("===================================================================");
2125: I(0,globl,"_Z80_Reset",0,0);
2126: S("_Z80_Reset",0);
2127: I(0,pushl, EBP, 0, 0);
2128: I(0,pushl, EBX, 0, 0);
2129: I(0,pushl, ESI, 0, 0);
2130: I(0,pushl, EDI, 0, 0);
2131: debug(1,"Z80_reset()\n");
2132: I(0,movl, EAX, D(0), 0);
2133: I(0,movl, EDI, O("_Z80"), "wipe out Z80 registers");
2134: I(0,movl, ECX, D(Z80_SIZE/4), 0);
2135: I(0,cld, 0, 0, 0);
2136: I(0,rep, 0, 0, 0);
2137: I(0,stosd, 0, 0, 0);
2138: I(0,movl, request_irq, D(-1), 0);
2139: I(0,movl, service_irq, D(-1), 0);
2140: I(0,movl, zSP32, X(0xf000), 0);
2141: I(0,movl, ESI, M(4,0,esp,20,0,0), "get daisy_chain");
2142: I(0,orl, ESI, ESI, "NULL ?");
2143: I(0,je, LS("z80_reset_3"),0, "yes, skip");
2144: I(0,movl, EBX, D(Z80_MAXDAISY), 0);
2145: I(0,movl, EDI, O("z80_irq"), "copy to z80_irq++");
2146:
2147: pad(align_loops);
2148: S("z80_reset_1",0);
2149: I(0,cmpl, M(4,0,esi,12,0,0),D(-1), "more entries?");
2150: I(0,je, LS("z80_reset_3"),0, 0);
2151: I(0,movl, EAX, M(4,0,esi,0,0,0), "get Z80.irq[device].reset");
2152: I(0,cmp, EAX, D(0), "handler?");
2153: I(0,je, LS("z80_reset_2"),0, "no, skip");
2154: I(0,pushl, M(4,0,esi,12,0,0),0, "Z80.irq[device].irq_param");
2155: I(0,call, EAX, 0, 0);
2156: I(0,addl, ESP, B(4), 0);
2157: S("z80_reset_2",0);
2158: I(0,cld, 0, 0, 0);
2159: I(0,movsd, 0, 0, 0);
2160: I(0,movsd, 0, 0, 0);
2161: I(0,movsd, 0, 0, 0);
2162: I(0,movsd, 0, 0, 0);
2163: I(0,incl, irq_max, 0, "count entries");
2164: I(0,decl, EBX, 0, "more to check?");
2165: I(0,jne, LS("z80_reset_1"),0, 0);
2166: S("z80_reset_3",0);
2167: I(0,movl, ECX, zPC32, 0);
2168: I(0,movl, EDI, MRHARD, 0);
2169: I(0,shrl, ECX, D(ABITS), 0);
2170: I(0,movb, CL, M(1,0,edi,0,ecx,1), 0);
2171: I(0,cmpb, CL, M(1,"_ophw",0,0,0,0),0);
2172: I(0,je, "z80_reset_4",0, 0);
2173: I(0,pushl, zPC32, 0, 0);
2174: I(0,call, "_cpu_setOPbase16",0, 0);
2175: I(0,addl, ESP, B(4), 0);
2176: S("z80_reset_4",0);
2177: dumpregs();
2178: I(0,popl, EDI, 0, 0);
2179: I(0,popl, ESI, 0, 0);
2180: I(0,popl, EBX, 0, 0);
2181: I(0,popl, EBP, 0, 0);
2182: I(0,ret, 0, 0, 0);
2183: com(0);
2184:
2185: pad(align_funcs);
2186: com("===================================================================");
2187: com(" int Z80_Execute(int cycles); ");
2188: com("===================================================================");
2189: I(0,globl,"_Z80_Execute",0,0);
2190: S("_Z80_Execute",0);
2191: I(0,pushl, EBP, 0, 0);
2192: I(0,pushl, EBX, 0, 0);
2193: I(0,pushl, ESI, 0, 0);
2194: I(0,pushl, EDI, 0, 0);
2195: I(0,movl, EAX, M(4,0,esp,20,0,0), "get the ICount");
2196: I(0,movl, ECX, D(0), 0);
2197: I(0,xchgl, ECX, zIEXTRN, "external cycles (interrupt)");
2198: I(0,movl, zITOTAL, EAX, "store total cycles");
2199: I(0,subl, EAX, ECX, "subtract from cycle count");
2200: I(0,movl, zICOUNT, EAX, "store cycles to run");
2201: debug(6,"Z80_execute(%d)\n",EAX);
2202: restore_af();
2203: restore_z80();
2204: I(0,jmp, "z80_next_opcode",0, 0);
2205:
2206: pad(align_funcs);
2207: com("===================================================================");
2208: com(" illegal opcode ");
2209: com("===================================================================");
2210: S("illop",0);
2211: debug(5,"illegal opcode $%04x: %02x\n", PC32, EAX);
2212:
2213: pad(align_funcs);
2214: com("===================================================================");
2215: com(" fetch next opcode ");
2216: com("===================================================================");
2217: S("z80_next_opcode",0);
2218: if (mame_debug) {
2219: com("===================================================================");
2220: com(" call MAME debugger ");
2221: com("===================================================================");
2222: I(0,testb, DEBUG, D(1), 0);
2223: I(0,je, LS("z80_no_debug"),0, 0);
2224: S("z80_mame_debug",0);
2225: mk_debug();
2226: S("z80_no_debug",0);
2227: }
2228: S("z80_next_opcode_1",0);
2229: ROP();
2230: I(0,jmp, M(4,"z_op",0,0,ecx,4),0, "jump to opcode handler");
2231:
2232: pad(align_funcs);
2233: S("z80_execute_done",0);
2234: save_z80(0);
2235: save_af();
2236: I(0,popl, EDI, 0, 0);
2237: I(0,popl, ESI, 0, 0);
2238: I(0,popl, EBX, 0, 0);
2239: I(0,popl, EBP, 0, 0);
2240: I(0,movl, EAX, zITOTAL, 0);
2241: I(0,subl, EAX, zICOUNT, 0);
2242: debug(6,"Z80_execute() : %d\n", EAX);
2243: I(0,ret, 0, 0, 0);
2244: com(0);
2245: }
2246:
2247: static void mk_rbyte_handler( int i )
2248: {
2249: #if FAST_MEMORY
2250: #define rTBL 1 /* jump table */
2251: #define rRAM 2 /* read RAM */
2252: #define rNOP 3 /* read NOP */
2253: #define rBNK 4 /* read bank memory */
2254: #define rRHW 5 /* readhardware */
2255: #define rUSR 6 /* read user (handler) */
2256: #define rNON 7 /* read unassigned memory */
2257:
2258: int j;
2259: char buffer[128+1], symbol[8][31+1];
2260: static UINT8 mr[256] = { /* MHELE (HT_XXX) to symbol mapping */
2261: rRAM,rBNK,rBNK,rBNK,rBNK,rBNK,rBNK,rBNK,rBNK,rNON,rNOP,rRAM,rRAM,rUSR,rUSR,rUSR,
2262: rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,
2263: rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,
2264: rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,rUSR,
2265: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2266: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2267: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2268: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2269: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2270: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2271: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2272: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2273: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2274: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2275: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,
2276: rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW,rRHW
2277: };
2278:
2279: sprintf(symbol[0], "rbyte%d", i);
2280: sprintf(symbol[rTBL], "rbyte%d_tbl", i);
2281: sprintf(symbol[rRAM], "rbyte0_ram"); /* not different due to opsize */
2282: sprintf(symbol[rNOP], "rbyte0_nop"); /* not different due to opsize */
2283: sprintf(symbol[rBNK], "rbyte0_bnk"); /* not different due to opsize */
2284: sprintf(symbol[rRHW], "rbyte%d_rhw", i);
2285: sprintf(symbol[rUSR], "rbyte%d_usr", i);
2286: sprintf(symbol[rNON], "rbyte%d_non", i);
2287:
2288: com("===================================================================");
2289: com(" read a byte from memory at EBP to EDX for opcodes of size %d ",i);
2290: com("===================================================================");
2291: pad(align_funcs);
2292: S(symbol[0],0);
2293: I(0,movl, ECX, EBP, "memory address to ECX");
2294: I(0,movl, EDI, MRHARD, "read flags");
2295: I(0,shrl, ECX, D(ABITS), ">> (ABITS2_16 + ABITS_MIN_16)");
2296: I(0,movzbl, EDX, M(1,0,edi,0,ecx,1), "get MHELE value");
2297: I(0,jmp, M(4,symbol[rTBL],0,0,edx,4),0, "jump to memory read function");
2298:
2299: I(0,data,0,0,0);
2300: pad(align_funcs);
2301: S(symbol[rTBL],0);
2302: for (j = 0; j < 256; j += 4) {
2303: sprintf(buffer,"%s,%s,%s,%s",symbol[mr[j+0]], symbol[mr[j+1]],symbol[mr[j+2]], symbol[mr[j+3]]);
2304: I(0,dd,buffer,0,0);
2305: }
2306: I(0,text,0,0,0);
2307:
2308: if (i == 0) { /* functions that are needed only once */
2309: pad(align_funcs);
2310: S(symbol[rRAM],"read HT_RAM, HT_RAMROM, HT_ROM");
2311: I(0,movl, EDI, RAM, "get RAM/ROM base");
2312: I(0,movb, DL, M(1,0,edi,0,ebp,1), "get byte from RAM/ROM");
2313: I(0,ret, 0, 0, 0);
2314:
2315: pad(align_funcs);
2316: S(symbol[rNOP],"read HT_NOP");
2317: I(0,movb, DL, D(0), "return zero");
2318: I(0,ret, 0, 0, 0);
2319:
2320: pad(align_funcs);
2321: S(symbol[rBNK],"read HT_BANK1 .. HT_BANK8");
2322: I(0,movl, ECX, EBP, "get address to ECX");
2323: I(0,movl, EDI, BANKBASE(edx), "get BANKn base");
2324: I(0,subl, ECX, READOFFSET(edx), "subtract read offset");
2325: I(0,movb, DL, M(1,0,edi,0,ecx,1), "get byte from BANKn");
2326: I(0,ret, 0, 0, 0);
2327: }
2328:
2329: pad(align_funcs);
2330: S(symbol[rRHW],"read MH_HARDMAX .. 255");
2331: I(0,movl, EDI, EDX, "get hw to EDI");
2332: I(0,movl, ECX, EBP, "address to ECX");
2333: I(0,shll, EDI, D(8), "hw << MH_SBITS");
2334: I(0,andl, ECX, B(15), "mask bits 0..3");
2335: I(0,movb, DL, READHW(edi,ecx), "get MHELE");
2336: I(0,jmp, M(4,symbol[rTBL],0,0,edx,4),0, "jump to read handler");
2337:
2338: pad(align_funcs);
2339: S(symbol[rUSR],"read HT_USER .. MH_HARDMAX-1");
2340: save_af();
2341: save_z80( i );
2342: I(0,movl, ECX, EBP, "get address to ECX");
2343: I(0,subl, ECX, READOFFSET(edx), "subtract read offset");
2344: I(0,movl, EDI, READHANDLER(edx), "get memoryreadhandler");
2345: I(0,pushl, ECX, 0, "offset");
2346: I(0,call, EDI, 0, "call handler");
2347: I(0,movl, EDX, EAX, "return value");
2348: I(0,addl, ESP, B(1*4), "one DWORD was pushed");
2349: restore_z80();
2350: restore_af();
2351: I(0,ret, 0, 0, 0);
2352:
2353: pad(align_funcs);
2354: S(symbol[rNON],"read HT_NON");
2355: save_af();
2356: save_z80( i );
2357: I(0,pushl, EBP, 0, "memory address");
2358: I(0,call, "_mrh_error",0, 0);
2359: I(0,movl, EDX, EAX, "return value");
2360: I(0,addl, ESP, B(1*4), "one DWORD was pushed");
2361: restore_z80();
2362: restore_af();
2363: I(0,ret, 0, 0, 0);
2364:
2365: #else
2366: char symbol[2][31+1];
2367: sprintf(symbol[0], "rbyte%d", i);
2368: sprintf(symbol[1], "rbyte%d_user", i);
2369:
2370: pad(align_funcs);
2371: com("===================================================================");
2372: com(" read a byte from memory at EBP to EDX for opcodes of size %d ",i);
2373: com("===================================================================");
2374: S(symbol[0],0);
2375: I(0,movl, ECX, EBP, "memory address to ECX");
2376: I(0,movl, EDI, MRHARD, "read flags");
2377: I(0,shrl, ECX, D(ABITS), ">> (ABITS2_16 + ABITS_MIN_16)");
2378: I(0,testb, M(1,0,edi,0,ecx,1),D(-1), "ROM/RAM?");
2379: I(0,jne, LS(symbol[1]),0, "nope, need to call handler");
2380: I(0,movl, EDI, RAM, "get RAM base");
2381: I(0,movzbl, EDX, M(1,0,edi,0,ebp,1), "get byte from RAM");
2382: I(0,ret, 0, 0, 0);
2383:
2384: pad(align_jumps);
2385: S(symbol[1],0);
2386: save_af();
2387: save_z80( i );
2388: I(0,pushl, EBP, 0, "memory address");
2389: I(0,call, "_cpu_readmem16",0, 0);
2390: I(0,movl, EDX, EAX, "return value");
2391: I(0,addl, ESP, B(1*4), "one DWORD was pushed");
2392: restore_z80();
2393: restore_af();
2394: I(0,ret, 0, 0, 0);
2395: #endif
2396: }
2397:
2398: static void mk_rword_handler( int i )
2399: {
2400: char symbol[3][15+1];
2401: sprintf(symbol[0], "rword%d", i);
2402: sprintf(symbol[1], "rword%d_usr", i);
2403: sprintf(symbol[2], "rbyte%d", i);
2404:
2405: pad(align_funcs);
2406: com("===================================================================");
2407: com(" read a word from memory at EBP to EDX for opcodes of size %d ",i);
2408: com("===================================================================");
2409: S(symbol[0],0);
2410: I(0,movl, ECX, EBP, "memory address to ECX");
2411: I(0,orl, ECX, B(15), "check if address...");
2412: I(0,cmpl, ECX, EBP, "...is 0xxxFh");
2413: I(0,je, LS(symbol[1]),0, "yes, need to read LSB then MSB");
2414: I(0,shrl, ECX, D(4), ">> (ABITS2_16 + ABITS_MIN_16)");
2415: I(0,movl, EDI, MRHARD, "read flags");
2416: I(0,testb, M(1,0,edi,0,ecx,1),D(-1), "MHELE == ROM/RAM?");
2417: I(0,jne, LS(symbol[1]),0, "nope, need to call handler");
2418: pad(align_funcs);
2419: I(0,movl, EDI, RAM, "get RAM base");
2420: I(0,movzwl, EDX, M(2,0,edi,0,ebp,1), "get word from ROM/RAM");
2421: I(0,ret, 0, 0, 0);
2422:
2423: pad(align_funcs);
2424: S(symbol[1],0);
2425: I(0,call, symbol[2], 0, "read LSB");
2426: I(0,incw, BP, 0, "address + 1");
2427: I(0,movb, zMB, DL, "save LSB value");
2428: I(0,call, symbol[2], 0, "read MSB");
2429: I(0,shll, EDX, D(8), "value to MSB");
2430: I(0,movb, DL, zMB, "get LSB");
2431: I(0,ret, 0, 0, 0);
2432: }
2433:
2434: static void mk_wbyte_handler( int i )
2435: {
2436: #if FAST_MEMORY
2437: #define wTBL 1 /* jump table */
2438: #define wRAM 2 /* write RAM */
2439: #define wNOP 3 /* don't write (NOP or ROM) */
2440: #define wRAR 4 /* write RAM and ROM */
2441: #define wBNK 5 /* write bank memory */
2442: #define wWHW 6 /* writehardware */
2443: #define wUSR 7 /* write user (handler) */
2444: #define wNON 8 /* write unassigned memory */
2445: int j;
2446: char buffer[128+1], symbol[9][31+1];
2447: static UINT8 mw[256] = { /* MHELE (HT_XXX) to symbol mapping */
2448: wRAM,wBNK,wBNK,wBNK,wBNK,wBNK,wBNK,wBNK,wBNK,wNON,wNOP,wRAR,wNOP,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,
2449: wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,wUSR,
2450: wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,
2451: wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,
2452: wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,
2453: wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,
2454: wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,
2455: wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW,wWHW
2456: };
2457:
2458: sprintf(symbol[0], "wbyte%d", i);
2459: sprintf(symbol[wTBL], "wbyte%d_tbl", i);
2460: sprintf(symbol[wRAM], "wbyte0_ram"); /* not different due to opsize */
2461: sprintf(symbol[wNOP], "wbyte0_nop"); /* not different due to opsize */
2462: sprintf(symbol[wRAR], "wbyte0_rar"); /* not different due to opsize */
2463: sprintf(symbol[wBNK], "wbyte0_bnk"); /* not different due to opsize */
2464: sprintf(symbol[wWHW], "wbyte%d_whw", i);
2465: sprintf(symbol[wUSR], "wbyte%d_usr", i);
2466: sprintf(symbol[wNON], "wbyte%d_non", i);
2467:
2468: com("===================================================================");
2469: com(" write a byte from EDX to memory at EBP for opcodes of size %d ",i);
2470: com("===================================================================");
2471: pad(align_funcs);
2472: S(symbol[0],0);
2473: I(0,movl, ECX, EBP, "memory address to ECX");
2474: I(0,movl, EDI, MWHARD, "write flags");
2475: I(0,shrl, ECX, D(ABITS), ">> (ABITS2_16 + ABITS_MIN_16)");
2476: I(0,movzbl, EDI, M(1,0,edi,0,ecx,1), "get MHELE value");
2477: I(0,jmp, M(4,symbol[wTBL],0,0,edi,4),0, "jump to memory write function");
2478:
2479: I(0,data,0,0,0);
2480: pad(align_funcs);
2481: S(symbol[wTBL],0);
2482: for (j = 0; j < 256; j += 4) {
2483: sprintf(buffer,"%s,%s,%s,%s",symbol[mw[j+0]], symbol[mw[j+1]],symbol[mw[j+2]], symbol[mw[j+3]]);
2484: I(0,dd,buffer,0,0);
2485: }
2486: I(0,text,0,0,0);
2487:
2488: if (i == 0) { /* functions that are needed only once */
2489: pad(align_funcs);
2490: S(symbol[wRAM],"HT_RAM");
2491: I(0,movl, EDI, RAM, "get RAM base");
2492: I(0,movb, M(1,0,edi,0,ebp,1), DL, "put byte into RAM");
2493: I(0,ret, 0, 0, 0);
2494:
2495: pad(align_funcs);
2496: S(symbol[wNOP],"HT_NOP");
2497: I(0,ret, 0, 0, "do nothing");
2498:
2499: pad(align_funcs);
2500: S(symbol[wRAR],"HT_RAMROM");
2501: I(0,movl, EDI, RAM, "get RAM base");
2502: I(0,movl, ECX, ROM, "get ROM base");
2503: I(0,movb, M(1,0,edi,0,ebp,1), DL, "put byte into RAM");
2504: I(0,movb, M(1,0,ecx,0,ebp,1), DL, "put byte into ROM");
2505: I(0,ret, 0, 0, 0);
2506:
2507: pad(align_funcs);
2508: S(symbol[wBNK],"HT_BANK1 - HT_BANK8");
2509: I(0,movl, ECX, EBP, "get address int0 ECX");
2510: I(0,subl, ECX, WRITEOFFSET(edi), "subtract write offset");
2511: I(0,movl, EDI, BANKBASE(edi), "get BANKn base");
2512: I(0,movb, M(1,0,edi,0,ecx,1), DL, "put byte to BANKn + offset");
2513: I(0,ret, 0, 0, 0);
2514: }
2515:
2516: pad(align_funcs);
2517: S(symbol[wWHW],"MH_HARDMAX..255");
2518: I(0,movl, ECX, EBP, "get address to ECX");
2519: I(0,shll, EDI, D(8), "hw << MH_SBITS");
2520: I(0,andl, ECX, B(15), "mask bits 0..3");
2521: I(0,movzbl, EDI, WRITEHW(edi,ecx), "get MHELE");
2522: I(0,jmp, M(4,symbol[wTBL],0,0,edi,4),0, "jump to write handler");
2523:
2524: pad(align_funcs);
2525: S(symbol[wUSR],"HT_USER .. MH_HARDMAX-1");
2526: save_af();
2527: save_z80( i );
2528: I(0,movl, ECX, EBP, "get address to ECX");
2529: I(0,pushl, EDX, 0, "data byte");
2530: I(0,subl, ECX, WRITEOFFSET(edi), "subtract write offset");
2531: I(0,movl, EDI, WRITEHANDLER(edi), "get memorywritehandler");
2532: I(0,pushl, ECX, 0, "offset");
2533: I(0,call, EDI, 0, "call handler");
2534: I(0,addl, ESP, B(2*4), "two DWORDs were pushed");
2535: restore_z80();
2536: restore_af();
2537: I(0,ret, 0, 0, 0);
2538:
2539: pad(align_funcs);
2540: S(symbol[wNON],"HT_NON");
2541: save_af();
2542: save_z80( i );
2543: I(0,pushl, EDX, 0, "data byte");
2544: I(0,pushl, EBP, 0, "memory address");
2545: I(0,call, "_mwh_error",0, 0);
2546: I(0,addl, ESP, B(2*4), "two DWORDs were pushed");
2547: restore_z80();
2548: restore_af();
2549: I(0,ret, 0, 0, 0);
2550:
2551: #else
2552: char symbol[2][31+1];
2553: sprintf(symbol[0], "wbyte%d", i);
2554: sprintf(symbol[1], "wbyte%d_user", i);
2555: pad(align_funcs);
2556: com("===================================================================");
2557: com(" write a byte from EDX to memory at EBP for opcodes of size %d ",i);
2558: com("===================================================================");
2559: S(symbol[0],0);
2560: I(0,movl, ECX, EBP, "get memory address to ECX");
2561: I(0,movl, EDI, MWHARD, "write flags");
2562: I(0,shrl, ECX, D(ABITS), ">> (ABITS2_16 + ABITS_MIN_16)");
2563: I(0,movzbl, ECX, M(1,0,edi,0,ecx,1), "get MHELE");
2564: I(0,orb, CL, CL, "write to RAM?");
2565: I(0,jne, LS(symbol[1]),0, "nope, need to call writemem16");
2566: I(0,movl, EDI, RAM, "get RAM base");
2567: I(0,movb, M(1,0,edi,0,ebp,1),DL, "store byte to RAM");
2568: I(0,ret, 0, 0, "return to caller");
2569:
2570: pad(align_jumps);
2571: S(symbol[1],0);
2572: save_af();
2573: save_z80( i );
2574: I(0,pushl, EDX, 0, "value");
2575: I(0,pushl, EBP, 0, "memory address");
2576: I(0,call, "_cpu_writemem16",0, 0);
2577: I(0,addl, ESP, B(2*4), "two DWORDs were pushed");
2578: restore_z80();
2579: restore_af();
2580: I(0,ret, 0, 0, "return to caller");
2581: #endif
2582: }
2583:
2584: static void mk_wword_handler( int i )
2585: {
2586: char symbol[3][15+1];
2587:
2588: sprintf(symbol[0], "wword%d", i);
2589: sprintf(symbol[1], "wword%d_usr", i);
2590: sprintf(symbol[2], "wbyte%d", i);
2591: pad(align_funcs);
2592: com("===================================================================");
2593: com(" write a word from EDX to memory at ECX for opcodes of size %d ",i);
2594: com("===================================================================");
2595: S(symbol[0],0);
2596: I(0,movl, ECX, EBP, "memory address to ECX");
2597: I(0,orb, CL, X(0x0f), "check if address...");
2598: I(0,cmpl, ECX, EBP, "...is 0xxxFh");
2599: I(0,je, LS(symbol[1]),0, "yes, need to write LSB then MSB");
2600: I(0,movl, EDI, MWHARD, "write flags");
2601: I(0,shrl, ECX, D(ABITS), ">> (ABITS2_16 + ABITS_MIN_16)");
2602: I(0,testb, M(1,0,edi,0,ecx,1),D(-1), "MHELE == RAM?");
2603: I(0,jne, LS(symbol[1]),0, "nope, need to call handler");
2604: pad(align_funcs);
2605: I(0,movl, EDI, RAM, "get RAM base");
2606: I(0,movw, M(2,0,edi,0,ebp,1),DX, "store word to RAM");
2607: I(0,ret, 0, 0, 0);
2608:
2609: pad(align_funcs);
2610: S(symbol[1],0);
2611: I(0,movb, zMB, DH, "save MSB of data");
2612: I(0,movzbl, EDX, DL, "EDX = LSB only");
2613: I(0,call, symbol[2], 0, "write LSB");
2614: I(0,incw, BP, 0, "address + 1");
2615: I(0,movzbl, EDX, zMB, "EDX = MSB only");
2616: I(0,call, symbol[2], 0, "write MSB");
2617: I(0,ret, 0, 0, 0);
2618: }
2619:
2620: static void mk_memory_handlers( void )
2621: {
2622: int i;
2623:
2624: for (i = 0; i <= 4*CALC_PREVPC; i++) {
2625: mk_rbyte_handler(i);
2626: mk_rword_handler(i);
2627: mk_wbyte_handler(i);
2628: mk_wword_handler(i);
2629: }
2630:
2631: com(0);
2632: com("===================================================================");
2633: com(" push PC to stack (called from interrupt handlers) ");
2634: com("===================================================================");
2635: pad(align_funcs);
2636: S("z80_push_pc",0);
2637: I(0,subw, zSP, B(2), 0);
2638: I(0,movzwl, EDX, PC, "get PC to EDX");
2639: I(0,movzwl, EBP, zSP, "get SP to EBP");
2640: I(0,jmp, "wword0", 0, "write word");
2641:
2642: com(0);
2643: com("===================================================================");
2644: com(" write back EDX to address EBP (DD/FD CB <ofs> xx opcodes) ");
2645: com("===================================================================");
2646: pad(align_funcs);
2647: S("wb_ea4_edx",0);
2648: #if CALC_PREVPC
2649: I(0,call, "wbyte4",0, "write the value in EDX");
2650: #else
2651: I(0,call, "wbyte0",0, "write the value in EDX");
2652: #endif
2653: end_opcode("z_op");
2654: }
2655:
2656: void M_INC( const char *dst )
2657: {
2658: I(0,shrb, F, D(1), "save carry");
2659: I(0,incb, dst, 0, 0);
2660: I(0,lahf, 0, 0, 0);
2661: I(0,seto, CL, 0, 0);
2662: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2663: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z,H and C");
2664: I(0,orb, F, CL, "combine the flags");
2665: }
2666:
2667: void M_DEC( const char *dst )
2668: {
2669: I(0,shrb, F, D(1), "save carry");
2670: I(0,decb, dst, 0, 0);
2671: I(0,lahf, 0, 0, 0);
2672: I(0,seto, CL, 0, 0);
2673: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2674: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z,H and C");
2675: I(0,orb, F, X(NF), "set N");
2676: I(0,orb, F, CL, "combine the flags");
2677: }
2678:
2679: void M_ADD16( const char *dst, const char *src )
2680: {
2681: I(0,movw, DX, dst, "get destination");
2682: I(0,movw, CX, src, "get source");
2683: I(0,addb, DL, CL, 0);
2684: I(0,adcb, DH, CH, 0);
2685: I(0,movb, CL, F, "get old flags");
2686: I(0,lahf, 0, 0, 0);
2687: I(0,andb, CL, X(SF|ZF|PF), "mask S,Z and P/V");
2688: I(0,movw, dst, DX, "store result");
2689: I(0,andb, F, X(HF|CF), "mask H and C");
2690: I(0,orb, F, CL, "set old flag bits");
2691: }
2692:
2693: void M_ADD( const char *src )
2694: {
2695: I(0,addb, A, src, "add source");
2696: I(0,lahf, 0, 0, 0);
2697: I(0,seto, CL, 0, 0);
2698: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2699: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z,H and C");
2700: I(0,orb, F, CL, "combine the flags");
2701: }
2702:
2703: void M_ADC( const char *src )
2704: {
2705: I(0,sahf, 0, 0, "set flags");
2706: I(0,adcb, A, src, "add source with carry");
2707: I(0,lahf, 0, 0, 0);
2708: I(0,seto, CL, 0, 0);
2709: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2710: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z,H and C");
2711: I(0,orb, F, CL, "combine the flags");
2712: }
2713:
2714: void M_SUB( const char *src )
2715: {
2716: I(0,subb, A, src, "subtract source");
2717: I(0,lahf, 0, 0, 0);
2718: I(0,seto, CL, 0, 0);
2719: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2720: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z,H and C");
2721: I(0,orb, F, X(NF), "set N");
2722: I(0,orb, F, CL, "combine the flags");
2723: }
2724:
2725: void M_SBC( const char *src )
2726: {
2727: I(0,sahf, 0, 0, "set the flags");
2728: I(0,sbbb, A, src, "subtract source with carry");
2729: I(0,lahf, 0, 0, 0);
2730: I(0,seto, CL, 0, 0);
2731: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2732: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z and C");
2733: I(0,orb, F, X(NF), "set N");
2734: I(0,orb, F, CL, "combine the flags");
2735: }
2736:
2737: void M_AND( const char *src )
2738: {
2739: I(0,andb, A, src, "logical and with source");
2740: I(0,lahf, 0, 0, 0);
2741: I(0,andb, F, X(SF|ZF|PF), "mask S,Z and P/V");
2742: I(0,orb, F, X(HF), "set H");
2743: }
2744:
2745: void M_XOR( const char *src )
2746: {
2747: I(0,xorb, A, src, "logical exclusive or with source");
2748: I(0,lahf, 0, 0, 0);
2749: I(0,andb, F, X(SF|ZF|PF), "mask S,Z and P/V");
2750: }
2751:
2752: void M_OR( const char *src )
2753: {
2754: I(0,orb, A, src, "logical or with source");
2755: I(0,lahf, 0, 0, 0);
2756: I(0,andb, F, X(SF|ZF|PF), "mask S,Z and P/V flags");
2757: }
2758:
2759: void M_CP( const char *src )
2760: {
2761: I(0,cmpb, A, src, "compare with source");
2762: I(0,lahf, 0, 0, 0);
2763: I(0,seto, CL, 0, 0);
2764: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
2765: I(0,andb, F, X(SF|ZF|HF|CF), "mask S,Z,H and C flags");
2766: I(0,orb, F, X(NF), "set N");
2767: I(0,orb, F, CL, "combine the flags");
2768: }
2769:
2770: #if BUSY_LOOP_HACKS
2771: void M_JR( int opcode )
2772: {
2773: char symbol[4][32+1];
2774: int i;
2775: for (i = 0; i < 4; i++)
2776: sprintf(symbol[i],"op_%02x_%d", opcode, i);
2777: I(0,movl, EDX, PC32, "ECX = old PC");
2778: I(0,decl, EDX, 0, "- 1");
2779: REL();
2780: I(0,addl, PC32, ECX, "change PC");
2781: I(0,cmpl, EDX, PC32, "busy loop (tight) ?");
2782: I(0,jne, LS(symbol[0]),0, "no, skip");
2783: I(0,orl, zICOUNT, B(0), "more cycles left?");
2784: I(0,jle, LN(symbol[3]),0, "no, skip");
2785: I(0,movl, zICOUNT, D(0), "bail out");
2786: I(0,jmp, symbol[3], 0, 0);
2787:
2788: pad(align_jumps);
2789: S(symbol[0],0);
2790: I(0,decl, EDX, 0, "EDX = oldpc - 1");
2791: I(0,movl, EDI, OP_ROM, "get OP_ROM base");
2792: I(0,movb, CL, M(1,0,edi,0,pc32,1), "read opcode byte");
2793: I(0,cmpl, EDX, PC32, "busy loop (1 byte opcode) ?");
2794: I(0,jne, LS(symbol[2]),0, "no, skip");
2795: I(0,cmpb, CL, X(0x00), "NOP - JR xxxx ?");
2796: I(0,jne, LS(symbol[1]),0, "no, skip");
2797: I(0,orl, zICOUNT, B(0), "more cycles left?");
2798: I(0,jle, LS(symbol[3]),0, "nope, leave");
2799: I(0,movl, zICOUNT, D(0), "bail out");
2800: I(0,jmp, symbol[3], 0, 0);
2801:
2802: pad(align_jumps);
2803: S(symbol[1],0);
2804: I(0,cmpb, CL, X(0xfb), "EI - JR xxxx ?");
2805: I(0,jne, LS(symbol[2]),0, "no, skip");
2806: I(0,cmpl, zICOUNT, B(4), "more than four cycles left?");
2807: I(0,jle, LS(symbol[3]),0, "nope, leave");
2808: I(0,movl, zICOUNT, D(4), "bail out after EI");
2809: I(0,jmp, symbol[3], 0, 0);
2810:
2811: pad(align_jumps);
2812: S(symbol[2],0);
2813: I(0,cmpb, CL, X(0x31), "LD SP,xxxx - JR xxxx ?");
2814: I(0,jne, LS(symbol[3]),0, "no, skip");
2815: I(0,subl, EDX, B(2), "EDX = oldpc - 3");
2816: I(0,cmpl, EDX, PC32, "busy loop (3 byte opcode) ?");
2817: I(0,jne, LS(symbol[3]),0, "no, skip");
2818: I(0,cmpl, zICOUNT, B(10), "more than ten cycles left?");
2819: I(0,jle, LS(symbol[3]),0, "nope, leave");
2820: I(0,movl, zICOUNT, D(10), "bail out after LD SP,xxxx");
2821: I(0,jmp, LS(symbol[3]),0, 0);
2822:
2823: pad(align_jumps);
2824: S(symbol[3],0);
2825: CHANGE_PC();
2826: }
2827: #else
2828: void M_JR( int opcode )
2829: {
2830: REL();
2831: I(0,addl, PC32, ECX, "change PC");
2832: CHANGE_PC();
2833: }
2834: #endif
2835:
2836: void M_JR_CC( int opcode, int flag )
2837: {
2838: char symbol[32+1];
2839: sprintf(symbol,"op_%02x_take", opcode);
2840: if (flag) {
2841: I(0,sahf, 0, 0, "set flags");
2842: switch (opcode & 0x38) {
2843: case 0x20: I(0,jnz, LS(symbol),0,"Z == 0: take jump"); break;
2844: case 0x28: I(0,jz, LS(symbol),0,"Z == 1: take jump"); break;
2845: case 0x30: I(0,jnc, LS(symbol),0,"C == 0: take jump"); break;
2846: case 0x38: I(0,jc, LS(symbol),0,"C == 1: take jump"); break;
2847: }
2848: ADJUST_PC(+1);
2849: end_opcode("z_op");
2850: }
2851:
2852: pad(align_jumps);
2853: S(symbol,"take the relative jump");
2854: REL();
2855: I(0,addl, PC32, ECX, "change PC");
2856: I(0,subl, zICOUNT,B(5), "five additional cycles");
2857: CHANGE_PC();
2858: }
2859:
2860: void M_DJNZ( int opcode )
2861: {
2862: char symbol[32+1];
2863: sprintf(symbol,"op_%02x_take ", opcode);
2864: I(0,decb, zB, 0, "decrement B");
2865: I(0,jne, LS(symbol),0, "not zero, take the jump");
2866: ADJUST_PC(+1);
2867: end_opcode("z_op");
2868:
2869: pad(align_jumps);
2870: S(symbol,"take the relative jump");
2871: REL();
2872: I(0,addl, PC32, ECX, "change PC");
2873: I(0,subl, zICOUNT,B(5), "five additional cycles");
2874: CHANGE_PC();
2875: }
2876:
2877: void M_HALT( int opcode )
2878: {
2879: char symbol[32+1];
2880: sprintf(symbol,"op_%02x_done", opcode);
2881: I(0,movb, zHALT, B(1), "set HALT flag");
2882: ADJUST_PC(-1);
2883: I(0,orl, zICOUNT, B(0), "cycle count <= zero already?");
2884: I(0,jle, LS(symbol), 0, 0);
2885: I(0,movl, zICOUNT, D(0), 0);
2886: S(symbol,0);
2887: }
2888:
2889: void M_RET( int opcode )
2890: {
2891: POP( 1, PC32 );
2892: CHANGE_PC();
2893: }
2894:
2895: void M_RET_CC( int opcode )
2896: {
2897: char symbol[32+1];
2898: sprintf(symbol,"op_%02x_done", opcode);
2899: I(0,sahf, 0, 0, "set flags");
2900: switch (opcode & 0x38) {
2901: case 0x00: I(0,jne, LS(symbol),0,"Z == 0: return"); break;
2902: case 0x08: I(0,je, LS(symbol),0,"Z == 1: return"); break;
2903: case 0x10: I(0,jnc, LS(symbol),0,"C == 0: return"); break;
2904: case 0x18: I(0,jc, LS(symbol),0,"C == 1: return"); break;
2905: case 0x20: I(0,jpo, LS(symbol),0,"P == 0: return"); break;
2906: case 0x28: I(0,jpe, LS(symbol),0,"P == 1: return"); break;
2907: case 0x30: I(0,jns, LS(symbol),0,"S == 0: return"); break;
2908: case 0x38: I(0,js, LS(symbol),0,"S == 1: return"); break;
2909: }
2910: end_opcode("z_op");
2911:
2912: pad(align_jumps);
2913: S(symbol,"execute the return");
2914: I(0,subl, zICOUNT,B(6), "six additional cycles");
2915: M_RET( opcode );
2916: }
2917:
2918: #if BUSY_LOOP_HACKS
2919: void M_JP( int opcode )
2920: {
2921: char symbol[4][32+1];
2922: int i;
2923: for (i = 0; i < 4; i++)
2924: sprintf(symbol[i],"op_%02x_%d", opcode, i);
2925: I(0,movl, ECX, PC32, "ECX = PC");
2926: I(0,decl, ECX, 0, "- 1");
2927: ARG16( PC32 );
2928: I(0,cmpl, ECX, PC32, "busy loop (tight) ?");
2929: I(0,jne, LS(symbol[0]),0, "no, skip");
2930: I(0,orl, zICOUNT, B(0), "more cycles left?");
2931: I(0,jle, LN(symbol[3]),0, "no, skip");
2932: I(0,movl, zICOUNT, D(0), "bail out");
2933: I(0,jmp, symbol[3], 0, 0);
2934: pad(align_jumps);
2935: S(symbol[0],0);
2936: I(0,decl, ECX, 0, "ECX = oldpc - 1");
2937: I(0,movl, EDI, OP_ROM, "get OP_ROM base");
2938: I(0,movb, DL, M(1,0,edi,0,pc32,1), "read opcode byte");
2939: I(0,cmpl, ECX, PC32, "busy loop (1 byte opcode) ?");
2940: I(0,jne, LS(symbol[2]),0, "no, skip");
2941: I(0,cmpb, DL, X(0x00), "NOP - JP xxxx ?");
2942: I(0,jne, LS(symbol[1]),0, "no, skip");
2943: I(0,orl, zICOUNT, B(0), "more cycles left?");
2944: I(0,jle, LS(symbol[3]),0, "nope, leave");
2945: I(0,movl, zICOUNT, D(0), "bail out");
2946: I(0,jmp, symbol[3], 0, 0);
2947: pad(align_jumps);
2948: S(symbol[1],0);
2949: I(0,cmpb, DL, X(0xfb), "EI - JP xxxx ?");
2950: I(0,jne, LS(symbol[2]),0, "no, skip");
2951: I(0,cmpl, zICOUNT, B(4), "more than four cycles left?");
2952: I(0,jle, LS(symbol[3]),0, "nope, leave");
2953: I(0,movl, zICOUNT, D(4), "bail out after EI");
2954: I(0,jmp, symbol[3], 0, 0);
2955: pad(align_jumps);
2956: S(symbol[2],0);
2957: I(0,cmpb, DL, X(0x31), "LD SP,xxxx - JP xxxx ?");
2958: I(0,jne, LS(symbol[3]),0, "no, skip");
2959: I(0,subl, ECX, B(2), "ECX = oldpc - 3");
2960: I(0,cmpl, ECX, PC32, "busy loop (3 byte opcode) ?");
2961: I(0,jne, LS(symbol[3]),0, "no, skip");
2962: I(0,cmpl, zICOUNT, B(10), "more than ten cycles left?");
2963: I(0,jle, LS(symbol[3]),0, "nope, leave");
2964: I(0,movl, zICOUNT, D(10), "bail out after LD SP,xxxx");
2965: I(0,jmp, LS(symbol[3]),0, 0);
2966: pad(align_jumps);
2967: S(symbol[3],0);
2968: CHANGE_PC();
2969: }
2970: #else
2971: void M_JP( int opcode )
2972: {
2973: ARG16( PC32 );
2974: CHANGE_PC();
2975: }
2976: #endif
2977:
2978: void M_JP_CC( int opcode )
2979: {
2980: char symbol[32+1];
2981: sprintf(symbol,"op_%02x_take", opcode);
2982: I(0,sahf, 0, 0, "set flags");
2983: switch (opcode & 0x38) {
2984: case 0x00: I(0,jne, LS(symbol),0,"Z == 0: jump"); break;
2985: case 0x08: I(0,je, LS(symbol),0,"Z == 1: jump"); break;
2986: case 0x10: I(0,jnc, LS(symbol),0,"C == 0: jump"); break;
2987: case 0x18: I(0,jc, LS(symbol),0,"C == 1: jump"); break;
2988: case 0x20: I(0,jpo, LS(symbol),0,"P == 0: jump"); break;
2989: case 0x28: I(0,jpe, LS(symbol),0,"P == 1: jump"); break;
2990: case 0x30: I(0,jns, LS(symbol),0,"S == 0: jump"); break;
2991: case 0x38: I(0,js, LS(symbol),0,"S == 1: jump"); break;
2992: }
2993: ADJUST_PC(+2);
2994: end_opcode("z_op");
2995:
2996: pad(align_jumps);
2997: S(symbol,"take the jump");
2998: ARG16( PC32 );
2999: CHANGE_PC();
3000: }
3001:
3002: void M_JP_REG( int opcode, const char *reg )
3003: {
3004: I(0,movl, PC32, reg, 0);
3005: CHANGE_PC();
3006: }
3007:
3008: void M_CALL( int opcode )
3009: {
3010: ARG16( zEA );
3011: PUSH( 3, PC32 );
3012: I(0,movl, PC32, zEA, "get the new PC");
3013: CHANGE_PC();
3014: }
3015:
3016: void M_CALL_CC( int opcode )
3017: {
3018: char symbol[32+1];
3019: sprintf(symbol,"op_%02x_take", opcode);
3020: I(0,sahf, 0, 0, "set flags");
3021: switch (opcode & 0x38) {
3022: case 0x00: I(0,jne, LS(symbol),0,"Z == 0: call"); break;
3023: case 0x08: I(0,je, LS(symbol),0,"Z == 1: call"); break;
3024: case 0x10: I(0,jnc, LS(symbol),0,"C == 0: call"); break;
3025: case 0x18: I(0,jc, LS(symbol),0,"C == 1: call"); break;
3026: case 0x20: I(0,jpo, LS(symbol),0,"P == 0: call"); break;
3027: case 0x28: I(0,jpe, LS(symbol),0,"P == 1: call"); break;
3028: case 0x30: I(0,jns, LS(symbol),0,"S == 0: call"); break;
3029: case 0x38: I(0,js, LS(symbol),0,"S == 1: call"); break;
3030: }
3031: ADJUST_PC(+2);
3032: end_opcode("z_op");
3033:
3034: pad(align_jumps);
3035: S(symbol,"make the call");
3036: ARG16( zEA );
3037: PUSH( 3, PC32 );
3038: I(0,movl, PC32, zEA, "get new PC");
3039: I(0,subl, zICOUNT,B(7), "seven additional cycles");
3040: CHANGE_PC();
3041: }
3042:
3043: void M_RST( int opcode )
3044: {
3045: PUSH( 1, PC32 );
3046: I(0,movl, PC32, X(opcode & 0x38), 0);
3047: CHANGE_PC();
3048: }
3049:
3050: void M_EX_AF_AF2( void )
3051: {
3052: I(0,xchgb, F, zF2, 0);
3053: I(0,xchgb, A, zA2, 0);
3054: }
3055:
3056: void M_EXX( void )
3057: {
3058: I(0,movzwl, ECX, zBC, 0);
3059: I(0,xchgw, CX, zBC2, 0);
3060: I(0,movw, zBC, CX, 0);
3061: I(0,movzwl, ECX, zDE, 0);
3062: I(0,xchgw, CX, zDE2, 0);
3063: I(0,movw, zDE, CX, 0);
3064: I(0,xchgw, HL, zHL2, 0);
3065: }
3066:
3067: void M_EX_DE_HL( void )
3068: {
3069: I(0,xchgw, HL, zDE, 0);
3070: }
3071:
3072: void M_RLCA( void )
3073: {
3074: I(0,shrb, F, D(1), "knock out C");
3075: I(0,rolb, A, D(1), 0);
3076: I(0,adcb, F, F, "get C");
3077: I(0,andb, F, X(~(HF|NF)&255),"remove H and N flags");
3078: }
3079:
3080: void M_RRCA( void )
3081: {
3082: I(0,shrb, F, D(1), "knock out C");
3083: I(0,rorb, A, D(1), 0);
3084: I(0,adcb, F, F, "get C");
3085: I(0,andb, F, X(~(HF|NF)&255),"remove H and N flags");
3086: }
3087:
3088: void M_RLA( void )
3089: {
3090: I(0,shrb, F, D(1), "C into carry");
3091: I(0,rclb, A, D(1), 0);
3092: I(0,adcb, F, F, "get C");
3093: I(0,andb, F, X(~(HF|NF)&255),"remove H and N flags");
3094: }
3095:
3096: void M_RRA( void )
3097: {
3098: I(0,shrb, F, D(1), "C into carry");
3099: I(0,rcrb, A, D(1), 0);
3100: I(0,adcb, F, F, "get C");
3101: I(0,andb, F, X(~(HF|NF)&255),"remove H and N flags");
3102: }
3103:
3104: void M_CPL( void )
3105: {
3106: I(0,xorb, A, X(0xff), "one's complement accumulator");
3107: I(0,orb, F, X(HF|NF), "set H and N");
3108: }
3109:
3110: void M_DAA( int opcode )
3111: {
3112: I(0,movzbl, ECX, A, "get accu");
3113: I(0,rorb, F, D(2), "check N flag");
3114: I(0,adcb, CH, CH, 0);
3115: I(0,rorb, F, D(3), "check H flag");
3116: I(0,adcb, CH, CH, 0);
3117: I(0,rorb, F, D(5), "check C flag");
3118: I(0,adcb, CH, CH, 0);
3119: I(0,movzwl, AF32, zDAA(ecx), "get DAA table entry");
3120: }
3121:
3122: void M_SCF( void )
3123: {
3124: I(0,andb, F, X(~(HF|NF)&255),"clear H and N");
3125: I(0,orb, F, X(CF), "set C");
3126: }
3127:
3128: void M_CCF( void )
3129: {
3130: I(0,movb, CL, F, 0);
3131: I(0,andb, F, X(~(HF|NF)),"clear H and N");
3132: I(0,andb, CL, X(CF), "mask C");
3133: I(0,shlb, CL, D(4), "move C to H");
3134: I(0,orb, CL, X(CF), "set C");
3135: I(0,xorb, F, CL, "toggle C, set/leave H");
3136: }
3137:
3138: void M_DI( void )
3139: {
3140: I(0,movb, zIFF1, D(0), "clear both interrupt flip-flops");
3141: I(0,movb, zIFF2, D(0), 0);
3142: }
3143:
3144: void M_EI( int opcode )
3145: {
3146: char symbol[32+1];
3147: sprintf(symbol, "op_%02x_skip", opcode);
3148: I(0,movb, CL, X(0xff), 0);
3149: I(0,movb, zIFF2, CL, "set interrupt flip-flop 2");
3150: I(0,cmpb, CL, zIFF1, "interrupt flip-flop 1 already set?");
3151: I(0,je, LN(symbol), 0, "yes, skip");
3152: I(0,movb, zIFF1, CL, "set IFF1");
3153: I(0,cmpl, irq_state, B(CLEAR_LINE), "irq line clear?");
3154: I(0,je, LN(symbol), 0, "yes, skip");
3155: save_af();
3156: save_z80(2);
3157: I(0,movl, ESI, zICOUNT, "save remaining cycle count");
3158: I(0,movl, EDI, zITOTAL, "and total cycle count");
3159: I(0,pushl, D(1), 0, "execute one opcode");
3160: I(0,call, "_Z80_Execute", 0, "recursive.. eww!");
3161: I(0,movl, zITOTAL, EDI, "restore total cycle count");
3162: I(0,movl, zICOUNT, ESI, "restore remaining cycle count");
3163: I(0,addl, ESP, B(4), "clean up stack");
3164: I(0,subl, zICOUNT, EAX, "subtract cycles used");
3165: restore_z80();
3166: restore_af();
3167: mk_take_irq( opcode );
3168: I(0,movl, ECX, D(0), 0);
3169: I(0,xchgl, ECX, zIEXTRN, "interrupt used cycles");
3170: I(0,subl, zICOUNT, ECX, "subtract from cycle count");
3171: com(0);
3172: pad(align_jumps);
3173: S(symbol,0);
3174: }
3175:
3176: void M_RLC( const char *reg )
3177: {
3178: I(0,rolb, reg, D(1), "rotate left circular");
3179: I(0,setc, CL, 0, "CL = 1 if carry set");
3180: I(0,orb, reg, D(0), "check sign, zero and parity");
3181: I(0,lahf, 0, 0, 0);
3182: I(0,andb, F, X(SF|ZF|PF), "mask S, Z and P/V flags");
3183: I(0,orb, F, CL, "combine with C");
3184: }
3185:
3186: void M_RRC( const char *reg )
3187: {
3188: I(0,rorb, reg, D(1), "rotate right circular");
3189: I(0,setc, CL, 0, "CL = 1 if carry set");
3190: I(0,orb, reg, D(0), "check sign, zero and parity");
3191: I(0,lahf, 0, 0, 0);
3192: I(0,andb, F, X(SF|ZF|PF), "mask S, Z and P/V flags");
3193: I(0,orb, F, CL, "combine with C");
3194: }
3195:
3196: void M_RL( const char *reg )
3197: {
3198: I(0,shrb, F, D(1), "get C into carry");
3199: I(0,rclb, reg, D(1), "rotate left through carry");
3200: I(0,setc, CL, 0, "CL = 1 if carry set");
3201: I(0,orb, reg, D(0), 0);
3202: I(0,lahf, 0, 0, 0);
3203: I(0,andb, F, X(SF|ZF|PF), "mask S,Z and P/V flags");
3204: I(0,orb, F, CL, "combine with C");
3205: }
3206:
3207: void M_RR( const char *reg )
3208: {
3209: I(0,shrb, F, D(1), "get C into carry");
3210: I(0,rcrb, reg, D(1), "rotate right through carry");
3211: I(0,setc, CL, 0, "CL = 1 if carry set");
3212: I(0,orb, reg, D(0), "check sign, zero and parity");
3213: I(0,lahf, 0, 0, 0);
3214: I(0,andb, F, X(SF|ZF|PF), "mask S,Z and P/V flags");
3215: I(0,orb, F, CL, "combine with C");
3216: }
3217:
3218: void M_SLL( const char *reg )
3219: {
3220: I(0,shlb, reg, D(1), "shift left logical");
3221: I(0,lahf, 0, 0, 0);
3222: I(0,andb, F, X(SF|PF|CF), "mask S, P/V and C flags");
3223: I(0,orb, reg, D(1), "set bit 0 of destination");
3224: }
3225:
3226: void M_SRL( const char *reg )
3227: {
3228: I(0,shrb, reg, D(1), "shift right logical");
3229: I(0,lahf, 0, 0, 0);
3230: I(0,andb, F, X(SF|ZF|PF|CF), "mask S, Z, P/V and C flags");
3231: }
3232:
3233: void M_SLA( const char *reg )
3234: {
3235: I(0,salb, reg, D(1), "shift left arithmetical (well..)");
3236: I(0,lahf, 0, 0, 0);
3237: I(0,andb, F, X(SF|ZF|PF|CF), "mask S, Z, P/V and C flags");
3238: }
3239:
3240: void M_SRA( const char *reg )
3241: {
3242: I(0,sarb, reg, D(1), "shift right arithmetical");
3243: I(0,lahf, 0, 0, 0);
3244: I(0,andb, F, X(SF|ZF|PF|CF), "mask S, Z, P/V and C flags");
3245: }
3246:
3247: void M_BIT( int n, const char *reg )
3248: {
3249: I(0,movb, CL, F, "save flags");
3250: I(0,movb, CH, X(1<<n), "bit mask");
3251: I(0,andb, CL, X(CF), "keep C flag");
3252: I(0,orb, CL, X(HF), "set H flag");
3253: I(0,andb, CH, reg, "check sign and zero");
3254: I(0,lahf, 0, 0, 0);
3255: I(0,andb, F, X(SF|ZF), "mask S and Z flags");
3256: I(0,orb, F, CL, "combine with C");
3257: }
3258:
3259: void M_RES( int n, const char *reg )
3260: {
3261: I(0,andb, reg, X(~(1<<n)&255), "reset bit mask");
3262: }
3263:
3264: void M_SET( int n, const char *reg )
3265: {
3266: I(0,orb, reg, X(1<<n), "set bit mask");
3267: }
3268:
3269: void M_OUT( int opsize, const char *port, const char *reg )
3270: {
3271: #if INLINE_IOPORTS
3272: static int wport = 0;
3273: char symbol[3][7+1];
3274: int i;
3275: wport++;
3276: for (i = 0; i < 3; i++)
3277: sprintf(symbol[i], "WP%03x_%d", wport, i);
3278: if (strcmp(reg, EDX))
3279: I(0,movzbl, EDX, reg, "output register");
3280: if (strcmp(port, ECX))
3281: I(0,movl, ECX, port, "output port");
3282: save_af();
3283: save_z80(opsize);
3284: I(0,movl, EDI, M(4,"_cur_writeport",0,0,0,0),0);
3285: I(0,orl, EDI, EDI, 0);
3286: I(0,je, LS(symbol[2]),0, 0);
3287: I(0,andl, ECX, M(4,"_cur_portmask",0,0,0,0),0);
3288: pad(align_jumps);
3289: S(symbol[0],0);
3290: I(0,cmpl, M(4,0,edi,0,0,0), D(-1), "end of table?");
3291: I(0,je, LS(symbol[2]),0, 0);
3292: I(0,cmpl, ECX, M(4,0,edi,0,0,0), "port < start?");
3293: I(0,jb, LS(symbol[1]),0, 0);
3294: I(0,cmpl, ECX, M(4,0,edi,4,0,0), "port > end?");
3295: I(0,ja, LS(symbol[1]),0, 0);
3296: I(0,movl, EBX, M(4,0,edi,8,0,0), "get handler");
3297: I(0,orl, EBX, EBX, "IOWP_NOP ?");
3298: I(0,je, LS(symbol[2]),0, 0);
3299: I(0,subl, ECX, M(4,0,edi,0,0,0), "subtract start");
3300: I(0,pushl, EDX, 0, "value");
3301: I(0,pushl, ECX, 0, "offset");
3302: I(0,call, EBX, 0, "call handler");
3303: I(0,addl, ESP, B(8), "two DWORDs were pushed");
3304: I(0,jmp, LS(symbol[2]),0, 0);
3305: pad(align_jumps);
3306: S(symbol[1],0);
3307: I(0,addl, EDI, B(12), "skip sizeof(IOWritePort)");
3308: I(0,jmp, LS(symbol[0]),0, "test next entry");
3309: pad(align_jumps);
3310: S(symbol[2],0);
3311: restore_z80();
3312: restore_af();
3313: #else
3314: if (strcmp(reg,EDX))
3315: I(0,movzbl, EDX, reg, "output register");
3316: if (strcmp(port,ECX))
3317: I(0,movl, ECX, port, "port");
3318: save_af();
3319: save_z80(opsize);
3320: I(0,pushl, EDX, 0, "value");
3321: I(0,pushl, ECX, 0, "port");
3322: I(0,call, "_cpu_writeport",0, 0);
3323: I(0,addl, ESP, B(8), "two DWORDs were pushed");
3324: restore_z80();
3325: restore_af();
3326: #endif
3327: }
3328:
3329: void M_IN( int opsize, const char *reg, const char *port )
3330: {
3331: #if INLINE_IOPORTS
3332: static int wport = 0;
3333: char symbol[3][7+1];
3334: int i;
3335: wport++;
3336: for (i = 0; i < 3; i++)
3337: sprintf(symbol[i], "RP%03x_%d", wport, i);
3338: if (strcmp(port,ECX))
3339: I(0,movl, ECX, port, "output port");
3340: save_af();
3341: save_z80(opsize);
3342: I(0,movl, EDI, M(4,"_cur_readport",0,0,0,0),0);
3343: I(0,orl, EDI, EDI, 0);
3344: I(0,je, LS(symbol[2]),0, 0);
3345: I(0,andl, ECX, M(4,"_cur_portmask",0,0,0,0),0);
3346: pad(align_jumps);
3347: S(symbol[0],0);
3348: I(0,cmpl, M(4,0,edi,0,0,0), D(-1), "end of table?");
3349: I(0,je, LS(symbol[2]),0, 0);
3350: I(0,cmpl, ECX, M(4,0,edi,0,0,0), "port < start?");
3351: I(0,jb, LS(symbol[1]),0, 0);
3352: I(0,cmpl, ECX, M(4,0,edi,4,0,0), "port > end?");
3353: I(0,ja, LS(symbol[1]),0, 0);
3354: I(0,movl, EAX, M(4,0,edi,8,0,0), "get handler");
3355: I(0,orl, EAX, EAX, "IORP_NOP ?");
3356: I(0,je, LS(symbol[2]),0, 0);
3357: I(0,subl, ECX, M(4,0,edi,0,0,0), "subtract start");
3358: I(0,pushl, ECX, 0, "offset");
3359: I(0,call, EAX, 0, "call handler");
3360: I(0,addl, ESP, B(4), 0);
3361: I(0,jmp, LS(symbol[2]),0, 0);
3362: pad(align_jumps);
3363: S(symbol[1],0);
3364: I(0,addl, EDI, B(12), "skip sizeof(IOReadPort)");
3365: I(0,jmp, LS(symbol[0]),0, "test next entry");
3366: pad(align_jumps);
3367: S(symbol[2],0);
3368: I(0,movzbl, EDX, AL, 0);
3369: restore_z80();
3370: restor_af();
3371: #else
3372: if (strcmp(port,ECX))
3373: I(0,movl, ECX, port, "output port");
3374: save_af();
3375: save_z80(opsize);
3376: I(0,pushl, ECX, 0, 0);
3377: I(0,call, "_cpu_readport",0, 0);
3378: I(0,addl, ESP, B(4), 0);
3379: I(0,movzbl, EDX, AL, 0);
3380: restore_z80();
3381: restore_af();
3382: #endif
3383: if (strcmp(reg, EDX) && strcmp(reg, DL))
3384: I(0,movb, reg, DL, "input register");
3385: }
3386:
3387: void M_OUT_BC( const char *reg )
3388: {
3389: I(0,movzbl, EDX, reg, "get value to EDX");
3390: M_OUT( 2, zBC32, EDX );
3391: }
3392:
3393: void M_IN_BC( const char *reg )
3394: {
3395: M_IN( 2, EDX, zBC32 );
3396: I(0,movb, CL, F, "save flags");
3397: I(0,andb, CL, X(CF), "mask C flag");
3398: I(0,orb, DL, DL, "check sign, zero and parity");
3399: I(0,lahf, 0, 0, 0);
3400: I(0,andb, F, X(SF|ZF|PF), "mask S, Z and P/V flags");
3401: if (strcmp(reg, DL))
3402: I(0,movb, reg, DL, 0);
3403: I(0,orb, F, CL, "combine with carry");
3404: }
3405:
3406: void M_ADC16( const char *src )
3407: {
3408: I(0,movw, DX, src, "get source");
3409: I(0,sahf, 0, 0, "set flags");
3410: I(0,adcb, L, DL, "add LSB");
3411: I(0,adcb, H, DH, "add with carry MSB");
3412: I(0,seto, CL, 0, "CL = 1 if overflow");
3413: I(0,lahf, 0, 0, 0);
3414: I(0,shlb, CL, D(2), "shift overflow to P/V bit position");
3415: I(0,andb, F, X(SF|HF|CF), "mask S, H and C flags");
3416: I(0,orb, F, CL, "combine with P/V");
3417: I(0,cmpl, HL32, B(0), "HL = zero?");
3418: I(0,setz, CL, 0, "CL = 1 if zero");
3419: I(0,shlb, CL, D(6), "shift zero to Z bit position");
3420: I(0,orb, F, CL, "combine with Z");
3421: }
3422:
3423: void M_SBC16( const char *src )
3424: {
3425: I(0,movw, DX, src, "get source");
3426: I(0,sahf, 0, 0, "set flags");
3427: I(0,sbbb, L, DL, 0);
3428: I(0,sbbb, H, DH, 0);
3429: I(0,seto, CL, 0, "F = 1 if overflow");
3430: I(0,lahf, 0, 0, 0);
3431: I(0,shlb, CL, D(2), "shift overflow to P/V bit position");
3432: I(0,andb, F, X(SF|HF|CF), "mask S, H and C flags");
3433: I(0,orb, F, CL, "combine with P/V");
3434: I(0,cmpl, HL32, B(0), "HL = zero?");
3435: I(0,setz, CL, 0, "CL = 1 if zero");
3436: I(0,orb, F, X(NF), "set N");
3437: I(0,shlb, CL, D(6), "shift zero to Z bit position");
3438: I(0,orb, F, CL, "combine with Z");
3439: }
3440:
3441: void M_NEG( void )
3442: {
3443: I(0,movb, CL, A, "get accumulator");
3444: I(0,movb, A, D(0), "subtract from zero");
3445: I(0,subb, A, CL, 0);
3446: I(0,lahf, 0, 0, 0);
3447: I(0,seto, CL, 0, "F = 1 if overflow");
3448: I(0,shlb, CL, D(2), "get overflow to P/V bit position");
3449: I(0,andb, F, X(SF|ZF|HF|CF), "mask S, Z, H and C flags");
3450: I(0,orb, F, X(NF), "set N");
3451: I(0,orb, F, CL, "combine with P/V");
3452: }
3453:
3454: void M_RETI( int opcode )
3455: {
3456: char symbol[32+1];
3457: sprintf(symbol,"ed_%02x_skip", opcode);
3458:
3459: POP( 2, PC32 );
3460: CHANGE_PC();
3461: I(0,movl, ECX, service_irq, 0);
3462: I(0,cmpl, ECX, B(0), 0);
3463: I(0,jl, LS(symbol),0, 0);
3464: save_af();
3465: save_z80(2);
3466: I(0,lea, ECX, M(0,0,0,0,ecx,4),"* sizeof(Z80_DaisyChain)");
3467: I(0,pushl, irq(ecx,12),0, "Z80.irq[device].irq_param");
3468: I(0,call, irq(ecx, 8),0, "Z80.irq[device].interrupt_reti");
3469: I(0,addl, ESP, B(4), 0);
3470: restore_z80();
3471: restore_af();
3472: pad(align_jumps);
3473: S(symbol,0);
3474: }
3475:
3476: void M_RETN( int opcode )
3477: {
3478: char symbol[32+1];
3479: sprintf(symbol,"ed_%02x_skip", opcode);
3480:
3481: POP( 2, PC32 );
3482: CHANGE_PC();
3483: I(0,movb, CL, zIFF2, "get interrupt flip-flop 2");
3484: I(0,orb, CL, CL, "will RETN enable interrupts?");
3485: I(0,je, LN(symbol),0, "no, skip");
3486: I(0,movb, zIFF1, CL, "copy to interrupt flip-flop 1");
3487: I(0,cmpl, irq_state, B(CLEAR_LINE),"irq line cleared?");
3488: I(0,je, LN(symbol),0, "yes, skip");
3489: mk_take_irq( opcode );
3490: I(0,movl, ECX, D(0), 0);
3491: I(0,xchgl, ECX, zIEXTRN, "interrupt used cycles");
3492: I(0,subl, zICOUNT, ECX, "subtract from cycle count");
3493: pad(align_jumps),
3494: S(symbol,0);
3495: }
3496:
3497: void M_LD_I_A( void )
3498: {
3499: I(0,movb, zI, A, 0);
3500: }
3501:
3502: void M_LD_A_I( void )
3503: {
3504: I(0,movb, CL, F, "save flags");
3505: I(0,movb, A, zI, 0);
3506: I(0,andb, CL, X(CF), "mask C flag");
3507: I(0,orb, A, A, "check sign and zero");
3508: I(0,lahf, 0, 0, 0);
3509: I(0,andb, F, X(SF|ZF), "mask S and Z flags");
3510: I(0,orb, F, CL, "combine with C");
3511: I(0,movb, CL, zIFF2, "get interrupt flip-flop 2");
3512: I(0,andb, CL, X(PF), "shift to P/V bit position");
3513: I(0,orb, F, CL, "get IFF2 into P/V");
3514: }
3515:
3516: void M_LD_R_A( void )
3517: {
3518: I(0,movb, CL, A, 0);
3519: I(0,movb, zR, CL, "store accu into R");
3520: I(0,andb, CL, X(0x80), "mask bit 7");
3521: I(0,movb, zR2, CL, "save in R2");
3522: }
3523:
3524: void M_LD_A_R( void )
3525: {
3526: I(0,movb, CL, F, "save flags");
3527: I(0,movb, A, zR, 0);
3528: I(0,andb, A, X(0x7f), "mask lower 7 bits");
3529: I(0,andb, CL, X(CF), "mask C flag");
3530: I(0,orb, A, zR2, "get bit 7 from original R");
3531: I(0,lahf, 0, 0, 0);
3532: I(0,andb, F, X(SF|ZF), "mask S and Z flags");
3533: I(0,orb, F, CL, "combine with C");
3534: I(0,movb, CL, zIFF2, "get interrupt flip-flop 2");
3535: I(0,andb, CL, X(PF), "shift to P/V bit position");
3536: I(0,orb, F, CL, "get IFF2 into P/V");
3537: }
3538:
3539: void M_RLD( void )
3540: {
3541: RBYTE( 2, EDX, HL32 );
3542: I(0,movb, CH, A, "get accu into CH");
3543: I(0,movb, CL, F, "save flags");
3544: I(0,andl, ECX, X(0x0f00|CF), "mask lower nibble and keep C flag");
3545: I(0,shll, EDX, D(4), "shift memory byte left one nibble");
3546: I(0,xorb, A, CH, "remove lower nibble from accu");
3547: I(0,orb, DL, CH, "put lower nibble of A into lower nibble of result");
3548: I(0,orb, A, DH, "put upper nibble of result into lower nibble of A");
3549: I(0,lahf, 0, 0, 0);
3550: I(0,andb, F, X(SF|ZF|PF), "mask S, Z and P/V flags");
3551: I(0,orb, F, CL, "combine with C");
3552: I(0,movzbl, EDX, DL, "EDX = result");
3553: WBYTE( 2, HL32, EDX );
3554: }
3555:
3556: void M_RRD( void )
3557: {
3558: RBYTE( 2, EDX, HL32 );
3559: I(0,movb, DH, A, "put A into MSB of result");
3560: I(0,rorw, DX, D(4), "DL = result, DH 4..7 = lower nibble of memory");
3561: I(0,movb, CL, F, "save flags");
3562: I(0,shrb, DH, D(4), "DH 0..3 = lower nibble of memory");
3563: I(0,andb, CL, X(CF), "keep C flag");
3564: I(0,andb, A, X(0xf0), "keep upper nibble of A");
3565: I(0,orb, A, DH, "set lower nibble from memory");
3566: I(0,lahf, 0, 0, 0);
3567: I(0,andb, F, X(SF|ZF|PF), "mask S, Z and P/V flags");
3568: I(0,orb, F, CL, "combine flags");
3569: I(0,movzbl, EDX, DL, "EDX = result");
3570: WBYTE( 2, HL32, EDX );
3571: }
3572:
3573: const char *s(char *fmt, ...)
3574: {
3575: va_list arg;
3576: static char buffer[128];
3577: va_start(arg, fmt);
3578: vsprintf(buffer, fmt, arg);
3579: va_end(arg);
3580: return buffer;
3581: }
3582:
3583: void mk_opcodes(int op_base)
3584: {
3585: char op[32];
3586: char hl[2+1], h[2+1], l[2+1], m[8+1];
3587: char zhl[32+1], zh[32+1], zl[32+1], zhl32[32+1];
3588: int mc = 0, mi = 0, mr = 0;
3589:
3590: if (op_base == 0xdd00) {
3591: strcpy(op,"dd_%02x"); /* opcode label mask */
3592: strcpy(hl,"IX"); /* word register name */
3593: strcpy(h,"HX"); /* MSB byte register name */
3594: strcpy(l,"LX"); /* LSB byte register name */
3595: strcpy(m,"(IX+ofs8)"); /* memory register name */
3596: strcpy(zh,zHX); /* MSB byte register */
3597: strcpy(zl,zLX); /* LSB byte register */
3598: strcpy(zhl,zIX); /* word register */
3599: strcpy(zhl32,zIX32); /* dword register */
3600: mc = 8; /* additional cycles for r/w (IX+ofs8) */
3601: mi = 5; /* additional cycles for w (IX+ofs8),imm8 */
3602: mr = 1; /* additional cycles for accessing IXL/IXH */
3603: } else
3604: if (op_base == 0xfd00) {
3605: strcpy(op,"fd_%02x"); /* opcode label mask */
3606: strcpy(hl,"IY"); /* word register name */
3607: strcpy(h,"HY"); /* MSB byte register name */
3608: strcpy(l,"LY"); /* LSB byte register name */
3609: strcpy(m,"(IY+ofs8)"); /* memory register name */
3610: strcpy(zh,zHY); /* MSB byte register */
3611: strcpy(zl,zLY); /* LSB byte register */
3612: strcpy(zhl,zIY); /* word register */
3613: strcpy(zhl32,zIY32); /* dword register */
3614: mc = 8; /* additional cycles for r/w (IY+ofs8) */
3615: mi = 5; /* additional cycles for w (IY+ofs8),imm8 */
3616: mr = 1; /* additional cycles for accessing IXL/IXH */
3617: } else {
3618: strcpy(op,"op_%02x"); /* opcode label mask */
3619: strcpy(hl,"HL"); /* word register name */
3620: strcpy(h,"H"); /* MSB byte register name */
3621: strcpy(l,"L"); /* LSB byte register name */
3622: strcpy(m,"(HL)"); /* memory register name */
3623: strcpy(zh,H); /* MSB byte register */
3624: strcpy(zl,L); /* LSB byte register */
3625: strcpy(zhl,HL); /* word register */
3626: strcpy(zhl32,HL32); /* dword register */
3627: }
3628:
3629: beg_opcode( 4,s(op,0x00),"NOP");
3630: end_opcode("z_op");
3631:
3632: beg_opcode( 4,s(op,0x08),"EX AF,AF'");
3633: M_EX_AF_AF2();
3634: end_opcode("z_op");
3635:
3636: beg_opcode( 8,s(op,0x10),"DJNZ ofs8");
3637: M_DJNZ( op_base|0x10 );
3638: end_opcode("z_op");
3639:
3640: beg_opcode(12,s(op,0x18),"JR ofs8");
3641: M_JR( op_base|0x18 );
3642: end_opcode("z_op");
3643:
3644: beg_opcode( 7,s(op,0x20),"JR NZ,ofs8");
3645: M_JR_CC( op_base|0x20, ZF );
3646: end_opcode("z_op");
3647:
3648: beg_opcode( 7,s(op,0x28),"JR Z,ofs8");
3649: M_JR_CC( op_base|0x28, ZF );
3650: end_opcode("z_op");
3651:
3652: beg_opcode( 7,s(op,0x30),"JR NC,ofs8");
3653: M_JR_CC( op_base|0x30, CF );
3654: end_opcode("z_op");
3655:
3656: beg_opcode( 7,s(op,0x38),"JR C,ofs8");
3657: M_JR_CC( op_base|0x38, CF );
3658: end_opcode("z_op");
3659:
3660: /*********/
3661:
3662: beg_opcode(10,s(op,0x01),"LD BC,imm16");
3663: ARG16( zBC32 );
3664: end_opcode("z_op");
3665:
3666: beg_opcode(10,s(op,0x11),"LD DE,imm16");
3667: ARG16( zDE32 );
3668: end_opcode("z_op");
3669:
3670: beg_opcode(10,s(op,0x21),"LD %s,imm16",hl);
3671: ARG16( zhl32 );
3672: end_opcode("z_op");
3673:
3674: beg_opcode(10,s(op,0x31),"LD SP,imm16");
3675: ARG16( zSP32 );
3676: end_opcode("z_op");
3677:
3678: /*********/
3679:
3680: beg_opcode(11,s(op,0x09),"ADD %s,BC",hl);
3681: M_ADD16( zhl, zBC );
3682: end_opcode("z_op");
3683:
3684: beg_opcode(11,s(op,0x19),"ADD %s,DE",hl);
3685: M_ADD16( zhl, zDE );
3686: end_opcode("z_op");
3687:
3688: beg_opcode(11,s(op,0x29),"ADD %s,%s",hl,hl);
3689: M_ADD16( zhl, zhl );
3690: end_opcode("z_op");
3691:
3692: beg_opcode(11,s(op,0x39),"ADD %s,SP",hl);
3693: M_ADD16( zhl, zSP );
3694: end_opcode("z_op");
3695:
3696: /*********/
3697:
3698: beg_opcode( 7,s(op,0x02),"LD (BC),A");
3699: I(0,movzbl, EDX, A, 0);
3700: WBYTE( 1, zBC32, EDX );
3701: end_opcode("z_op");
3702:
3703: beg_opcode( 7,s(op,0x0a),"LD A,(BC)");
3704: RBYTE( 1, EDX, zBC32 );
3705: I(0,movb, A, DL, 0);
3706: end_opcode("z_op");
3707:
3708: beg_opcode( 7,s(op,0x12),"LD (DE),A");
3709: I(0,movzbl, EDX, A, 0);
3710: WBYTE( 1, zDE32, EDX );
3711: end_opcode("z_op");
3712:
3713: beg_opcode( 7,s(op,0x1a),"LD A,(DE)");
3714: RBYTE( 1, EDX, zDE32 );
3715: I(0,movb, A, DL, 0);
3716: end_opcode("z_op");
3717:
3718: beg_opcode(16,s(op,0x22),"LD (imm16),%s",hl);
3719: ARG16( EBP );
3720: WWORD( (op_base)?4:3, EBP, zhl32 );
3721: end_opcode("z_op");
3722:
3723: beg_opcode(16,s(op,0x2a),"LD %s,(imm16)",hl);
3724: ARG16( EBP );
3725: RWORD( (op_base)?4:3, zhl32, EBP );
3726: end_opcode("z_op");
3727:
3728: beg_opcode(13,s(op,0x32),"LD (imm16),A");
3729: ARG16( EBP );
3730: I(0,movzbl, EDX, A, 0);
3731: WBYTE( 3, EBP, EDX );
3732: end_opcode("z_op");
3733:
3734: beg_opcode(13,s(op,0x3a),"LD A,(imm16)");
3735: ARG16( EBP );
3736: RBYTE( 3, EDX, EBP );
3737: I(0,movb, A, DL, 0);
3738: end_opcode("z_op");
3739:
3740: /*********/
3741:
3742: beg_opcode( 6,s(op,0x03),"INC BC");
3743: I(0,incw, zBC, 0, 0);
3744: end_opcode("z_op");
3745:
3746: beg_opcode( 6,s(op,0x0b),"DEC BC");
3747: I(0,decw, zBC, 0, 0);
3748: end_opcode("z_op");
3749:
3750: beg_opcode( 6,s(op,0x13),"INC DE");
3751: I(0,incw, zDE, 0, 0);
3752: end_opcode("z_op");
3753:
3754: beg_opcode( 6,s(op,0x1b),"DEC DE");
3755: I(0,decw, zDE, 0, 0);
3756: end_opcode("z_op");
3757:
3758: beg_opcode( 6,s(op,0x23),"INC %s",hl);
3759: I(0,incw, zhl, 0, 0);
3760: end_opcode("z_op");
3761:
3762: beg_opcode( 6,s(op,0x2b),"DEC %s",hl);
3763: I(0,decw, zhl, 0, 0);
3764: end_opcode("z_op");
3765:
3766: beg_opcode( 6,s(op,0x33),"INC SP");
3767: I(0,incw, zSP, 0, 0);
3768: end_opcode("z_op");
3769:
3770: beg_opcode( 6, s(op,0x3b),"DEC SP");
3771: I(0,decw, zSP, 0, 0);
3772: end_opcode("z_op");
3773:
3774: /*********/
3775:
3776: beg_opcode( 4,s(op,0x04),"INC B");
3777: M_INC( zB );
3778: end_opcode("z_op");
3779:
3780: beg_opcode( 4,s(op,0x0c),"INC C");
3781: M_INC( zC );
3782: end_opcode("z_op");
3783:
3784: beg_opcode( 4,s(op,0x14),"INC D");
3785: M_INC( zD );
3786: end_opcode("z_op");
3787:
3788: beg_opcode( 4,s(op,0x1c),"INC E");
3789: M_INC( zE );
3790: end_opcode("z_op");
3791:
3792: beg_opcode( 4+mr,s(op,0x24),"INC %s",h);
3793: M_INC( zh );
3794: end_opcode("z_op");
3795:
3796: beg_opcode( 4+mr,s(op,0x2c),"INC %s",l);
3797: M_INC( zl );
3798: end_opcode("z_op");
3799:
3800: beg_opcode(11+mc,s(op,0x34),"INC %s",m);
3801: if (op_base) {
3802: OFS( zhl32 );
3803: RBYTE( 3, EDX, EBP );
3804: M_INC( DL );
3805: WBYTE( 3, EBP, EDX );
3806: } else {
3807: RBYTE( 1, EDX, HL32 );
3808: M_INC( DL );
3809: WBYTE( 1, HL32, EDX );
3810: }
3811: end_opcode("z_op");
3812:
3813: beg_opcode( 4,s(op,0x3c),"INC A");
3814: M_INC( A );
3815: end_opcode("z_op");
3816:
3817: /*********/
3818:
3819: beg_opcode( 4,s(op,0x05),"DEC B");
3820: M_DEC( zB );
3821: end_opcode("z_op");
3822:
3823: beg_opcode( 4,s(op,0x0d),"DEC C");
3824: M_DEC( zC );
3825: end_opcode("z_op");
3826:
3827: beg_opcode( 4,s(op,0x15),"DEC D");
3828: M_DEC( zD );
3829: end_opcode("z_op");
3830:
3831: beg_opcode( 4,s(op,0x1d),"DEC E");
3832: M_DEC( zE );
3833: end_opcode("z_op");
3834:
3835: beg_opcode( 4+mr,s(op,0x25),"DEC %s",h);
3836: M_DEC( zh );
3837: end_opcode("z_op");
3838:
3839: beg_opcode( 4+mr,s(op,0x2d),"DEC %s",l);
3840: M_DEC( zl );
3841: end_opcode("z_op");
3842:
3843: beg_opcode(11+mc,s(op,0x35),"DEC %s",m);
3844: if (op_base) {
3845: OFS( zhl32 );
3846: RBYTE( 3, EDX, EBP );
3847: M_DEC( DL );
3848: WBYTE( 3, EBP, EDX );
3849: } else {
3850: RBYTE( 1, EDX, HL32 );
3851: M_DEC( DL );
3852: WBYTE( 1, HL32, EDX );
3853: }
3854: end_opcode("z_op");
3855:
3856: beg_opcode( 4,s(op,0x3d),"DEC A");
3857: M_DEC( A );
3858: end_opcode("z_op");
3859:
3860: /*********/
3861:
3862: beg_opcode( 7,s(op,0x06),"LD B,imm8");
3863: ARG( CL );
3864: I(0,movb, zB, CL, 0);
3865: end_opcode("z_op");
3866:
3867: beg_opcode( 7,s(op,0x0e),"LD C,imm8");
3868: ARG( CL );
3869: I(0,movb, zC, CL, 0);
3870: end_opcode("z_op");
3871:
3872: beg_opcode( 7,s(op,0x16),"LD D,imm8");
3873: ARG( CL );
3874: I(0,movb, zD, CL, 0);
3875: end_opcode("z_op");
3876:
3877: beg_opcode( 7,s(op,0x1e),"LD E,imm8");
3878: ARG( CL );
3879: I(0,movb, zE, CL, 0);
3880: end_opcode("z_op");
3881:
3882: if ( op_base ) {
3883: beg_opcode( 5,s(op,0x26),"LD %s,imm8",h);
3884: ARG( CL );
3885: I(0,movb, zh, CL, 0);
3886: } else {
3887: beg_opcode( 7,s(op,0x26),"LD %s,imm8",h);
3888: ARG( zh );
3889: }
3890: end_opcode("z_op");
3891:
3892: if ( op_base ) {
3893: beg_opcode( 5,s(op,0x2e),"LD %s,imm8",l);
3894: ARG( CL );
3895: I(0,movb, zl, CL, 0);
3896: } else {
3897: beg_opcode( 7,s(op,0x2e),"LD %s,imm8",l);
3898: ARG( zl );
3899: }
3900: end_opcode("z_op");
3901:
3902: beg_opcode(10+mi,s(op,0x36),"LD %s,imm8",m);
3903: if (op_base) {
3904: OFS( zhl32 );
3905: ARG( EDX );
3906: #if WB_EA4_EDX
3907: I(0,jmp, "wb_ea4_edx",0, 0);
3908: #else
3909: WBYTE( 4, EBP, EDX );
3910: end_opcode("z_op");
3911: #endif
3912: } else {
3913: ARG( EDX );
3914: WBYTE( 2, HL32, EDX );
3915: end_opcode("z_op");
3916: }
3917:
3918: beg_opcode( 7,s(op,0x3e),"LD A,imm8");
3919: ARG( CL );
3920: I(0,movb, A, CL, 0);
3921: end_opcode("z_op");
3922:
3923: /*********/
3924:
3925: beg_opcode( 4,s(op,0x1f),"RRA");
3926: M_RRA();
3927: end_opcode("z_op");
3928:
3929: beg_opcode( 4,s(op,0x07),"RLCA");
3930: M_RLCA();
3931: end_opcode("z_op");
3932:
3933: beg_opcode( 4,s(op,0x0f),"RRCA");
3934: M_RRCA();
3935: end_opcode("z_op");
3936:
3937: beg_opcode( 4,s(op,0x17),"RLA");
3938: M_RLA();
3939: end_opcode("z_op");
3940:
3941: beg_opcode( 4,s(op,0x27),"DAA");
3942: M_DAA( op_base|0x27 );
3943: end_opcode("z_op");
3944:
3945: beg_opcode( 4,s(op,0x2f),"CPL");
3946: M_CPL();
3947: end_opcode("z_op");
3948:
3949: beg_opcode( 4,s(op,0x37),"SCF");
3950: M_SCF();
3951: end_opcode("z_op");
3952:
3953: beg_opcode( 4,s(op,0x3f),"CCF");
3954: M_CCF();
3955: end_opcode("z_op");
3956:
3957: /*********/
3958:
3959: beg_opcode( 4,s(op,0x40),"LD B,B");
3960: MOVB( zB, zB, "B = B" );
3961: end_opcode("z_op");
3962:
3963: beg_opcode( 4,s(op,0x41),"LD B,C");
3964: MOVB( zB, zC, "B = C" );
3965: end_opcode("z_op");
3966:
3967: beg_opcode( 4,s(op,0x42),"LD B,D");
3968: MOVB( zB, zD, "B = D" );
3969: end_opcode("z_op");
3970:
3971: beg_opcode( 4,s(op,0x43),"LD B,E");
3972: MOVB( zB, zE, "B = E" );
3973: end_opcode("z_op");
3974:
3975: beg_opcode( 4+mr,s(op,0x44),"LD B,%s",h);
3976: MOVB( zB, zh, "B = %s", h );
3977: end_opcode("z_op");
3978:
3979: beg_opcode( 4+mr,s(op,0x45),"LD B,%s",l);
3980: MOVB( zB, zl, "B = %s", l );
3981: end_opcode("z_op");
3982:
3983: beg_opcode( 7+mc,s(op,0x46),"LD B,%s",m);
3984: if (op_base) {
3985: OFS( zhl32 );
3986: RBYTE( 3, EDX, EBP );
3987: } else {
3988: RBYTE( 1, EDX, HL32 );
3989: }
3990: MOVB( zB, DL, "B = %s", m );
3991: end_opcode("z_op");
3992:
3993: beg_opcode( 4,s(op,0x47),"LD B,A");
3994: MOVB( zB, A, "B = A" );
3995: end_opcode("z_op");
3996:
3997: /*********/
3998:
3999: beg_opcode( 4,s(op,0x48),"LD C,B");
4000: MOVB( zC, zB, "C = B" );
4001: end_opcode("z_op");
4002:
4003: beg_opcode( 4,s(op,0x49),"LD C,C");
4004: MOVB( zC, zC, "C = C" );
4005: end_opcode("z_op");
4006:
4007: beg_opcode( 4,s(op,0x4a),"LD C,D");
4008: MOVB( zC, zD, "C = D" );
4009: end_opcode("z_op");
4010:
4011: beg_opcode( 4,s(op,0x4b),"LD C,E");
4012: MOVB( zC, zE, "C = E" );
4013: end_opcode("z_op");
4014:
4015: beg_opcode( 4+mr,s(op,0x4c),"LD C,%s",h);
4016: MOVB( zC, zh, "C = %s", h );
4017: end_opcode("z_op");
4018:
4019: beg_opcode( 4+mr,s(op,0x4d),"LD C,%s",l);
4020: MOVB( zC, zl, "C = %s", l );
4021: end_opcode("z_op");
4022:
4023: beg_opcode( 7+mc,s(op,0x4e),"LD C,%s",m);
4024: if (op_base) {
4025: OFS( zhl32 );
4026: RBYTE( 3, EDX, EBP );
4027: } else {
4028: RBYTE( 1, EDX, HL32 );
4029: }
4030: MOVB( zC, DL, "C = %s", m );
4031: end_opcode("z_op");
4032:
4033: beg_opcode( 4,s(op,0x4f),"LD C,A");
4034: MOVB( zC, A, "C = A" );
4035: end_opcode("z_op");
4036:
4037: /*********/
4038:
4039: beg_opcode( 4,s(op,0x50),"LD D,B");
4040: MOVB( zD, zB, "D = B" );
4041: end_opcode("z_op");
4042:
4043: beg_opcode( 4,s(op,0x51),"LD D,C");
4044: MOVB( zD, zC, "D = C" );
4045: end_opcode("z_op");
4046:
4047: beg_opcode( 4,s(op,0x52),"LD D,D");
4048: MOVB( zD, zD, "D = D" );
4049: end_opcode("z_op");
4050:
4051: beg_opcode( 4,s(op,0x53),"LD D,E");
4052: MOVB( zD, zE, "D = E" );
4053: end_opcode("z_op");
4054:
4055: beg_opcode( 4+mr,s(op,0x54),"LD D,%s",h);
4056: MOVB( zD, zh, "D = %s", h );
4057: end_opcode("z_op");
4058:
4059: beg_opcode( 4+mr,s(op,0x55),"LD D,%s",l);
4060: MOVB( zD, zl, "D = %s", l );
4061: end_opcode("z_op");
4062:
4063: beg_opcode( 7+mc,s(op,0x56),"LD D,%s",m);
4064: if (op_base) {
4065: OFS( zhl32 );
4066: RBYTE( 3, EDX, EBP );
4067: } else {
4068: RBYTE( 1, EDX, HL32 );
4069: }
4070: MOVB( zD, DL, "D = %s", m );
4071: end_opcode("z_op");
4072:
4073: beg_opcode( 4,s(op,0x57),"LD D,A");
4074: MOVB( zD, A, "D = A" );
4075: end_opcode("z_op");
4076:
4077: /*********/
4078:
4079: beg_opcode( 4,s(op,0x58),"LD E,B");
4080: MOVB( zE, zB, "E = B" );
4081: end_opcode("z_op");
4082:
4083: beg_opcode( 4,s(op,0x59),"LD E,C");
4084: MOVB( zE, zC, "E = C" );
4085: end_opcode("z_op");
4086:
4087: beg_opcode( 4,s(op,0x5a),"LD E,D");
4088: MOVB( zE, zD, "E = D" );
4089: end_opcode("z_op");
4090:
4091: beg_opcode( 4,s(op,0x5b),"LD E,E");
4092: MOVB( zE, zE, "E = E" );
4093: end_opcode("z_op");
4094:
4095: beg_opcode( 4+mr,s(op,0x5c),"LD E,%s",h);
4096: MOVB( zE, zh, "E = %s", h );
4097: end_opcode("z_op");
4098:
4099: beg_opcode( 4+mr,s(op,0x5d),"LD E,%s",l);
4100: MOVB( zE, zl, "E = %s", l );
4101: end_opcode("z_op");
4102:
4103: beg_opcode( 7+mc,s(op,0x5e),"LD E,%s",m);
4104: if (op_base) {
4105: OFS( zhl32 );
4106: RBYTE( 3, EDX, EBP );
4107: } else {
4108: RBYTE( 1, EDX, HL32 );
4109: }
4110: MOVB( zE, DL, "E = %s", m );
4111: end_opcode("z_op");
4112:
4113: beg_opcode( 4,s(op,0x5f),"LD E,A");
4114: MOVB( zE, A, "E = A" );
4115: end_opcode("z_op");
4116:
4117: /*********/
4118:
4119: beg_opcode( 4+mr,s(op,0x60),"LD %s,B",h);
4120: MOVB( zh, zB, "%s = B", h );
4121: end_opcode("z_op");
4122:
4123: beg_opcode( 4+mr,s(op,0x61),"LD %s,C",h);
4124: MOVB( zh, zC, "%s = C", h );
4125: end_opcode("z_op");
4126:
4127: beg_opcode( 4+mr,s(op,0x62),"LD %s,D",h);
4128: MOVB( zh, zD, "%s = D", h );
4129: end_opcode("z_op");
4130:
4131: beg_opcode( 4+mr,s(op,0x63),"LD %s,E",h);
4132: MOVB( zh, zE, "%s = E", h );
4133: end_opcode("z_op");
4134:
4135: beg_opcode( 4+mr,s(op,0x64),"LD %s,%s",h,h);
4136: MOVB( zh, zh, "%s = %s", h, h );
4137: end_opcode("z_op");
4138:
4139: beg_opcode( 4+mr,s(op,0x65),"LD %s,%s",h,l);
4140: MOVB( zh, zl, "%s = %s", h, l );
4141: end_opcode("z_op");
4142:
4143: beg_opcode( 7+mc,s(op,0x66),"LD H,%s",m);
4144: if (op_base) {
4145: OFS( zhl32 );
4146: RBYTE( 3, EDX, EBP );
4147: } else {
4148: RBYTE( 1, EDX, HL32 );
4149: }
4150: MOVB( H, DL, "H = %s", m );
4151: end_opcode("z_op");
4152:
4153: beg_opcode( 4+mr,s(op,0x67),"LD %s,A",h);
4154: MOVB( zh, A, "%s = A", h );
4155: end_opcode("z_op");
4156:
4157: /*********/
4158:
4159: beg_opcode( 4+mr,s(op,0x68),"LD %s,B",l);
4160: MOVB( zl, zB, "%s = B", l );
4161: end_opcode("z_op");
4162:
4163: beg_opcode( 4+mr,s(op,0x69),"LD %s,C",l);
4164: MOVB( zl, zC, "%s = C", l );
4165: end_opcode("z_op");
4166:
4167: beg_opcode( 4+mr,s(op,0x6a),"LD %s,D",l);
4168: MOVB( zl, zD, "%s = D", l );
4169: end_opcode("z_op");
4170:
4171: beg_opcode( 4+mr,s(op,0x6b),"LD %s,E",l);
4172: MOVB( zl, zE, "%s = E", l );
4173: end_opcode("z_op");
4174:
4175: beg_opcode( 4+mr,s(op,0x6c),"LD %s,%s",l,h);
4176: MOVB( zl, zh, "%s = %s", l, h );
4177: end_opcode("z_op");
4178:
4179: beg_opcode( 4+mr,s(op,0x6d),"LD %s,%s",l,l);
4180: MOVB( zl, zl, "%s = %s", l, l );
4181: end_opcode("z_op");
4182:
4183: beg_opcode( 7+mc,s(op,0x6e),"LD L,%s",m);
4184: if (op_base) {
4185: OFS( zhl32 );
4186: RBYTE( 3, EDX, EBP );
4187: } else {
4188: RBYTE( 1, EDX, HL32 );
4189: }
4190: MOVB( L, DL, "L = %s", m );
4191: end_opcode("z_op");
4192:
4193: beg_opcode( 4+mr,s(op,0x6f),"LD %s,A",l);
4194: MOVB( zl, A, "%s = A", l );
4195: end_opcode("z_op");
4196:
4197: /*********/
4198:
4199: beg_opcode( 7+mc,s(op,0x70),"LD %s,B",m);
4200: MOVB( EDX, zB, "%s = B", m );
4201: if (op_base) {
4202: OFS( zhl32 );
4203: WBYTE( 3, EBP, EDX );
4204: } else {
4205: WBYTE( 1, HL32, EDX );
4206: }
4207: end_opcode("z_op");
4208:
4209: beg_opcode( 7+mc,s(op,0x71),"LD %s,C",m);
4210: MOVB( EDX, zC, "%s = C", m );
4211: if (op_base) {
4212: OFS( zhl32 );
4213: WBYTE( 3, EBP, EDX );
4214: } else {
4215: WBYTE( 1, HL32, EDX );
4216: }
4217: end_opcode("z_op");
4218:
4219: beg_opcode( 7+mc,s(op,0x72),"LD %s,D",m);
4220: MOVB( EDX, zD, "%s = D", m );
4221: if (op_base) {
4222: OFS( zhl32 );
4223: WBYTE( 3, EBP, EDX );
4224: } else {
4225: WBYTE( 1, HL32, EDX );
4226: }
4227: end_opcode("z_op");
4228:
4229: beg_opcode( 7+mc,s(op,0x73),"LD %s,E",m);
4230: MOVB( EDX, zE, "%s = E", m );
4231: if (op_base) {
4232: OFS( zhl32 );
4233: WBYTE( 3, EBP, EDX );
4234: } else {
4235: WBYTE( 1, HL32, EDX );
4236: }
4237: end_opcode("z_op");
4238:
4239: beg_opcode( 7+mc,s(op,0x74),"LD %s,H",m);
4240: MOVB( EDX, H, "%s = H", m );
4241: if (op_base) {
4242: OFS( zhl32 );
4243: WBYTE( 3, EBP, EDX );
4244: } else {
4245: WBYTE( 1, HL32, EDX );
4246: }
4247: end_opcode("z_op");
4248:
4249: beg_opcode( 7+mc,s(op,0x75),"LD %s,L",m);
4250: MOVB( EDX, L, "%s = L", m );
4251: if (op_base) {
4252: OFS( zhl32 );
4253: WBYTE( 3, EBP, EDX );
4254: } else {
4255: WBYTE( 1, HL32, EDX );
4256: }
4257: end_opcode("z_op");
4258:
4259: beg_opcode( 4,s(op,0x76),"HALT");
4260: M_HALT( op_base|0x76 );
4261: end_opcode("z_op");
4262:
4263: beg_opcode( 7+mc,s(op,0x77),"LD %s,A",m);
4264: MOVB( EDX, A, "%s = A", m );
4265: if (op_base) {
4266: OFS( zhl32 );
4267: WBYTE( 3, EBP, EDX );
4268: } else {
4269: WBYTE( 1, HL32, EDX );
4270: }
4271: end_opcode("z_op");
4272:
4273: /*********/
4274:
4275: beg_opcode( 4,s(op,0x78),"LD A,B");
4276: MOVB( A, zB, "A = B" );
4277: end_opcode("z_op");
4278:
4279: beg_opcode( 4,s(op,0x79),"LD A,C");
4280: MOVB( A, zC, "A = C" );
4281: end_opcode("z_op");
4282:
4283: beg_opcode( 4,s(op,0x7a),"LD A,D");
4284: MOVB( A, zD, "A = D" );
4285: end_opcode("z_op");
4286:
4287: beg_opcode( 4,s(op,0x7b),"LD A,E");
4288: MOVB( A, zE, "A = E" );
4289: end_opcode("z_op");
4290:
4291: beg_opcode( 4+mr,s(op,0x7c),"LD A,%s",h);
4292: MOVB( A, zh, "A = %s", h );
4293: end_opcode("z_op");
4294:
4295: beg_opcode( 4+mr,s(op,0x7d),"LD A,%s",l);
4296: MOVB( A, zl, "A = %s", l );
4297: end_opcode("z_op");
4298:
4299: beg_opcode( 7+mc,s(op,0x7e),"LD A,%s",m);
4300: if (op_base) {
4301: OFS( zhl32 );
4302: RBYTE( 3, EDX, EBP );
4303: } else {
4304: RBYTE( 1, EDX, HL32 );
4305: }
4306: MOVB( A, DL, "A = %s", m );
4307: end_opcode("z_op");
4308:
4309: beg_opcode( 4,s(op,0x7f),"LD A,A");
4310: MOVB( A, A, "A = A" );
4311: end_opcode("z_op");
4312:
4313: /*********/
4314:
4315: beg_opcode( 4,s(op,0x80),"ADD A,B");
4316: M_ADD( zB );
4317: end_opcode("z_op");
4318:
4319: beg_opcode( 4,s(op,0x81),"ADD A,C");
4320: M_ADD( zC );
4321: end_opcode("z_op");
4322:
4323: beg_opcode( 4,s(op,0x82),"ADD A,D");
4324: M_ADD( zD );
4325: end_opcode("z_op");
4326:
4327: beg_opcode( 4,s(op,0x83),"ADD A,E");
4328: M_ADD( zE );
4329: end_opcode("z_op");
4330:
4331: beg_opcode( 4+mr,s(op,0x84),"ADD A,%s",h);
4332: M_ADD( zh );
4333: end_opcode("z_op");
4334:
4335: beg_opcode( 4+mr,s(op,0x85),"ADD A,%s",l);
4336: M_ADD( zl );
4337: end_opcode("z_op");
4338:
4339: beg_opcode( 7+mc,s(op,0x86),"ADD A,%s",m);
4340: if (op_base) {
4341: OFS( zhl32 );
4342: RBYTE( 3, EDX, EBP );
4343: } else {
4344: RBYTE( 1, EDX, HL32 );
4345: }
4346: M_ADD( DL );
4347: end_opcode("z_op");
4348:
4349: beg_opcode( 4,s(op,0x87),"ADD A,A");
4350: M_ADD( A );
4351: end_opcode("z_op");
4352:
4353: /*********/
4354:
4355: beg_opcode( 4,s(op,0x88),"ADC A,B");
4356: M_ADC( zB );
4357: end_opcode("z_op");
4358:
4359: beg_opcode( 4,s(op,0x89),"ADC A,C");
4360: M_ADC( zC );
4361: end_opcode("z_op");
4362:
4363: beg_opcode( 4,s(op,0x8a),"ADC A,D");
4364: M_ADC( zD );
4365: end_opcode("z_op");
4366:
4367: beg_opcode( 4,s(op,0x8b),"ADC A,E");
4368: M_ADC( zE );
4369: end_opcode("z_op");
4370:
4371: beg_opcode( 4+mr,s(op,0x8c),"ADC A,%s",h);
4372: M_ADC( zh );
4373: end_opcode("z_op");
4374:
4375: beg_opcode( 4+mr,s(op,0x8d),"ADC A,%s",l);
4376: M_ADC( zl );
4377: end_opcode("z_op");
4378:
4379: beg_opcode( 7+mc,s(op,0x8e),"ADC A,%s",m);
4380: if (op_base) {
4381: OFS( zhl32 );
4382: RBYTE( 3, EDX, EBP );
4383: } else {
4384: RBYTE( 1, EDX, HL32 );
4385: }
4386: M_ADC( DL );
4387: end_opcode("z_op");
4388:
4389: beg_opcode( 4,s(op,0x8f),"ADC A,A");
4390: M_ADC( A );
4391: end_opcode("z_op");
4392:
4393: /*********/
4394:
4395: beg_opcode( 4,s(op,0x90),"SUB B");
4396: M_SUB( zB );
4397: end_opcode("z_op");
4398:
4399: beg_opcode( 4,s(op,0x91),"SUB C");
4400: M_SUB( zC );
4401: end_opcode("z_op");
4402:
4403: beg_opcode( 4,s(op,0x92),"SUB D");
4404: M_SUB( zD );
4405: end_opcode("z_op");
4406:
4407: beg_opcode( 4,s(op,0x93),"SUB E");
4408: M_SUB( zE );
4409: end_opcode("z_op");
4410:
4411: beg_opcode( 4+mr,s(op,0x94),"SUB %s",h);
4412: M_SUB( zh );
4413: end_opcode("z_op");
4414:
4415: beg_opcode( 4+mr,s(op,0x95),"SUB %s",l);
4416: M_SUB( zl );
4417: end_opcode("z_op");
4418:
4419: beg_opcode( 7+mc,s(op,0x96),"SUB %s",m);
4420: if (op_base) {
4421: OFS( zhl32 );
4422: RBYTE( 3, EDX, EBP );
4423: } else {
4424: RBYTE( 1, EDX, HL32 );
4425: }
4426: M_SUB( DL );
4427: end_opcode("z_op");
4428:
4429: beg_opcode( 4,s(op,0x97),"SUB A");
4430: M_SUB( A );
4431: end_opcode("z_op");
4432:
4433: /*********/
4434:
4435: beg_opcode( 4,s(op,0x98),"SBC A,B");
4436: M_SBC( zB );
4437: end_opcode("z_op");
4438:
4439: beg_opcode( 4,s(op,0x99),"SBC A,C");
4440: M_SBC( zC );
4441: end_opcode("z_op");
4442:
4443: beg_opcode( 4,s(op,0x9a),"SBC A,D");
4444: M_SBC( zD );
4445: end_opcode("z_op");
4446:
4447: beg_opcode( 4,s(op,0x9b),"SBC A,E");
4448: M_SBC( zE );
4449: end_opcode("z_op");
4450:
4451: beg_opcode( 4+mr,s(op,0x9c),"SBC A,%s",h);
4452: M_SBC( zh );
4453: end_opcode("z_op");
4454:
4455: beg_opcode( 4+mr,s(op,0x9d),"SBC A,%s",l);
4456: M_SBC( zl );
4457: end_opcode("z_op");
4458:
4459: beg_opcode( 7+mc,s(op,0x9e),"SBC A,%s",m);
4460: if (op_base) {
4461: OFS( zhl32 );
4462: RBYTE( 3, EDX, EBP );
4463: } else {
4464: RBYTE( 1, EDX, HL32 );
4465: }
4466: M_SBC( DL );
4467: end_opcode("z_op");
4468:
4469: beg_opcode( 4,s(op,0x9f),"SBC A,A");
4470: M_SBC( A );
4471: end_opcode("z_op");
4472:
4473: /*********/
4474:
4475: beg_opcode( 4,s(op,0xa0),"AND B");
4476: M_AND( zB );
4477: end_opcode("z_op");
4478:
4479: beg_opcode( 4,s(op,0xa1),"AND C");
4480: M_AND( zC );
4481: end_opcode("z_op");
4482:
4483: beg_opcode( 4,s(op,0xa2),"AND D");
4484: M_AND( zD );
4485: end_opcode("z_op");
4486:
4487: beg_opcode( 4,s(op,0xa3),"AND E");
4488: M_AND( zE );
4489: end_opcode("z_op");
4490:
4491: beg_opcode( 4+mr,s(op,0xa4),"AND %s",h);
4492: M_AND( zh );
4493: end_opcode("z_op");
4494:
4495: beg_opcode( 4+mr,s(op,0xa5),"AND %s",l);
4496: M_AND( zl );
4497: end_opcode("z_op");
4498:
4499: beg_opcode( 7+mc,s(op,0xa6),"AND %s",m);
4500: if (op_base) {
4501: OFS( zhl32 );
4502: RBYTE( 3, EDX, EBP );
4503: } else {
4504: RBYTE( 1, EDX, HL32 );
4505: }
4506: M_AND( DL );
4507: end_opcode("z_op");
4508:
4509: beg_opcode( 4,s(op,0xa7),"AND A");
4510: M_AND( A );
4511: end_opcode("z_op");
4512:
4513: /*********/
4514:
4515: beg_opcode( 4,s(op,0xa8),"XOR B");
4516: M_XOR( zB );
4517: end_opcode("z_op");
4518:
4519: beg_opcode( 4,s(op,0xa9),"XOR C");
4520: M_XOR( zC );
4521: end_opcode("z_op");
4522:
4523: beg_opcode( 4,s(op,0xaa),"XOR D");
4524: M_XOR( zD );
4525: end_opcode("z_op");
4526:
4527: beg_opcode( 4,s(op,0xab),"XOR E");
4528: M_XOR( zE );
4529: end_opcode("z_op");
4530:
4531: beg_opcode( 4+mr,s(op,0xac),"XOR %s",h);
4532: M_XOR( zh );
4533: end_opcode("z_op");
4534:
4535: beg_opcode( 4+mr,s(op,0xad),"XOR %s",l);
4536: M_XOR( zl );
4537: end_opcode("z_op");
4538:
4539: beg_opcode( 7+mc,s(op,0xae),"XOR %s",m);
4540: if (op_base) {
4541: OFS( zhl32 );
4542: RBYTE( 3, EDX, EBP );
4543: } else {
4544: RBYTE( 1, EDX, HL32 );
4545: }
4546: M_XOR( DL );
4547: end_opcode("z_op");
4548:
4549: beg_opcode( 4,s(op,0xaf),"XOR A");
4550: M_XOR( A );
4551: end_opcode("z_op");
4552:
4553: /*********/
4554:
4555: beg_opcode( 4,s(op,0xb0),"OR B");
4556: M_OR( zB );
4557: end_opcode("z_op");
4558:
4559: beg_opcode( 4,s(op,0xb1),"OR C");
4560: M_OR( zC );
4561: end_opcode("z_op");
4562:
4563: beg_opcode( 4,s(op,0xb2),"OR D");
4564: M_OR( zD );
4565: end_opcode("z_op");
4566:
4567: beg_opcode( 4,s(op,0xb3),"OR E");
4568: M_OR( zE );
4569: end_opcode("z_op");
4570:
4571: beg_opcode( 4+mr,s(op,0xb4),"OR %s",h);
4572: M_OR( zh );
4573: end_opcode("z_op");
4574:
4575: beg_opcode( 4+mr,s(op,0xb5),"OR %s",l);
4576: M_OR( zl );
4577: end_opcode("z_op");
4578:
4579: beg_opcode( 7+mc,s(op,0xb6),"OR %s",m);
4580: if (op_base) {
4581: OFS( zhl32 );
4582: RBYTE( 3, EDX, EBP );
4583: } else {
4584: RBYTE( 1, EDX, HL32 );
4585: }
4586: M_OR( DL );
4587: end_opcode("z_op");
4588:
4589: beg_opcode( 4,s(op,0xb7),"OR A");
4590: M_OR( A );
4591: end_opcode("z_op");
4592:
4593: /*********/
4594:
4595: beg_opcode( 4,s(op,0xb8),"CP B");
4596: M_CP( zB );
4597: end_opcode("z_op");
4598:
4599: beg_opcode( 4,s(op,0xb9),"CP C");
4600: M_CP( zC );
4601: end_opcode("z_op");
4602:
4603: beg_opcode( 4,s(op,0xba),"CP D");
4604: M_CP( zD );
4605: end_opcode("z_op");
4606:
4607: beg_opcode( 4,s(op,0xbb),"CP E");
4608: M_CP( zE );
4609: end_opcode("z_op");
4610:
4611: beg_opcode( 4+mr,s(op,0xbc),"CP %s",h);
4612: M_CP( zh );
4613: end_opcode("z_op");
4614:
4615: beg_opcode( 4+mr,s(op,0xbd),"CP %s",l);
4616: M_CP( zl );
4617: end_opcode("z_op");
4618:
4619: beg_opcode( 7+mc,s(op,0xbe),"CP %s",m);
4620: if (op_base) {
4621: OFS( zhl32 );
4622: RBYTE( 3, EDX, EBP );
4623: } else {
4624: RBYTE( 1, EDX, HL32 );
4625: }
4626: M_CP( DL );
4627: end_opcode("z_op");
4628:
4629: beg_opcode( 4,s(op,0xbf),"CP A");
4630: M_CP( A );
4631: end_opcode("z_op");
4632:
4633: /*********/
4634:
4635: beg_opcode( 5,s(op,0xc0),"RET NZ");
4636: M_RET_CC( op_base|0xc0 );
4637: end_opcode("z_op");
4638:
4639: beg_opcode( 5,s(op,0xc8),"RET Z");
4640: M_RET_CC( op_base|0xc8 );
4641: end_opcode("z_op");
4642:
4643: beg_opcode( 5,s(op,0xd0),"RET NC");
4644: M_RET_CC( op_base|0xd0 );
4645: end_opcode("z_op");
4646:
4647: beg_opcode( 5,s(op,0xd8),"RET C");
4648: M_RET_CC( op_base|0xd8 );
4649: end_opcode("z_op");
4650:
4651: beg_opcode( 5,s(op,0xe0),"RET PE");
4652: M_RET_CC( op_base|0xe0 );
4653: end_opcode("z_op");
4654:
4655: beg_opcode( 5,s(op,0xe8),"RET PO");
4656: M_RET_CC( op_base|0xe8 );
4657: end_opcode("z_op");
4658:
4659: beg_opcode( 5,s(op,0xf0),"RET P");
4660: M_RET_CC( op_base|0xf0 );
4661: end_opcode("z_op");
4662:
4663: beg_opcode( 5,s(op,0xf8),"RET M");
4664: M_RET_CC( op_base|0xf8 );
4665: end_opcode("z_op");
4666:
4667: /*********/
4668:
4669: beg_opcode(10,s(op,0xc1),"POP BC");
4670: POP( 1, zBC32 );
4671: end_opcode("z_op");
4672:
4673: beg_opcode(10,s(op,0xd1),"POP DE");
4674: POP( 1, zDE32 );
4675: end_opcode("z_op");
4676:
4677: beg_opcode(10,s(op,0xe1),"POP %s",hl);
4678: POP( (op_base)?2:1, zhl32 );
4679: end_opcode("z_op");
4680:
4681: beg_opcode(10,s(op,0xf1),"POP AF");
4682: POP( 1, zAF32 );
4683: restore_af();
4684: end_opcode("z_op");
4685:
4686: beg_opcode(11,s(op,0xc5),"PUSH BC");
4687: PUSH( 1, zBC32 );
4688: end_opcode("z_op");
4689:
4690: beg_opcode(11,s(op,0xd5),"PUSH DE");
4691: PUSH( 1, zDE32 );
4692: end_opcode("z_op");
4693:
4694: beg_opcode(11,s(op,0xe5),"PUSH %s",hl);
4695: PUSH( (op_base)?2:1, zhl32 );
4696: end_opcode("z_op");
4697:
4698: beg_opcode(11,s(op,0xf5),"PUSH AF");
4699: save_af();
4700: PUSH( 1, zAF32 );
4701: end_opcode("z_op");
4702:
4703: /*********/
4704:
4705: beg_opcode(10,s(op,0xc2),"JP NZ,imm16");
4706: M_JP_CC( op_base|0xc2 );
4707: end_opcode("z_op");
4708:
4709: beg_opcode(10,s(op,0xca),"JP Z,imm16");
4710: M_JP_CC( op_base|0xca );
4711: end_opcode("z_op");
4712:
4713: beg_opcode(10,s(op,0xd2),"JP NC,imm16");
4714: M_JP_CC( op_base|0xd2 );
4715: end_opcode("z_op");
4716:
4717: beg_opcode(10,s(op,0xda),"JP C,imm16");
4718: M_JP_CC( op_base|0xda );
4719: end_opcode("z_op");
4720:
4721: beg_opcode(10,s(op,0xe2),"JP PE,imm16");
4722: M_JP_CC( op_base|0xe2 );
4723: end_opcode("z_op");
4724:
4725: beg_opcode(10,s(op,0xea),"JP PO,imm16");
4726: M_JP_CC( op_base|0xea );
4727: end_opcode("z_op");
4728:
4729: beg_opcode(10,s(op,0xf2),"JP P,imm16");
4730: M_JP_CC( op_base|0xf2 );
4731: end_opcode("z_op");
4732:
4733: beg_opcode(10,s(op,0xfa),"JP M,imm16");
4734: M_JP_CC( op_base|0xfa );
4735: end_opcode("z_op");
4736:
4737: /*********/
4738:
4739: beg_opcode(10,s(op,0xc3),"JP imm16");
4740: M_JP( op_base|0xc3 );
4741: end_opcode("z_op");
4742:
4743: if (op_base) {
4744: beg_opcode( 0,s(op,0xcb),"%02x CB <ofs8> xx", op_base >> 8);
4745: OFS( zhl32 );
4746: RBYTE( 3, EDX, EBP );
4747: end_opcode("z_xx");
4748: } else {
4749: beg_opcode( 0,s(op,0xcb),"CB xx");
4750: end_opcode("z_cb");
4751: }
4752:
4753: beg_opcode(11,s(op,0xd3),"OUT (imm8),A");
4754: ARG( ECX );
4755: I(0,movzbl, EDX, A, "value");
4756: I(0,movb, CH, A, "16 bit port A on upper 8 address lines");
4757: M_OUT( 2, ECX, EDX );
4758: end_opcode("z_op");
4759:
4760: beg_opcode(11,s(op,0xdb),"IN A,(imm8)");
4761: ARG( ECX );
4762: I(0,movb, CH, A, "16 bit port A on upper 8 address lines");
4763: M_IN( 2, EDX, ECX );
4764: I(0,movb, A, DL, "get result");
4765: end_opcode("z_op");
4766:
4767: beg_opcode(19,s(op,0xe3),"EX (SP),%s",hl);
4768: RWORD( (op_base)?2:1, EDX, zSP32 );
4769: I(0,xchgw, DX, zhl, 0);
4770: WWORD( (op_base)?2:1, zSP32, EDX );
4771: end_opcode("z_op");
4772:
4773: beg_opcode( 4,s(op,0xeb),"EX DE,HL");
4774: M_EX_DE_HL();
4775: end_opcode("z_op");
4776:
4777: beg_opcode( 4,s(op,0xf3),"DI");
4778: M_DI();
4779: end_opcode("z_op");
4780:
4781: beg_opcode( 4,s(op,0xfb),"EI");
4782: M_EI( op_base|0xfb );
4783: end_opcode("z_op");
4784:
4785: /*********/
4786:
4787: beg_opcode(10,s(op,0xc4),"CALL NZ,imm16");
4788: M_CALL_CC( op_base|0xc4 );
4789: end_opcode("z_op");
4790:
4791: beg_opcode(10,s(op,0xcc),"CALL Z,imm16");
4792: M_CALL_CC( op_base|0xcc );
4793: end_opcode("z_op");
4794:
4795: beg_opcode(10,s(op,0xd4),"CALL NC,imm16");
4796: M_CALL_CC( op_base|0xd4 );
4797: end_opcode("z_op");
4798:
4799: beg_opcode(10,s(op,0xdc),"CALL C,imm16");
4800: M_CALL_CC( op_base|0xdc );
4801: end_opcode("z_op");
4802:
4803: beg_opcode(10,s(op,0xe4),"CALL PE,imm16");
4804: M_CALL_CC( op_base|0xe4 );
4805: end_opcode("z_op");
4806:
4807: beg_opcode(10,s(op,0xec),"CALL PO,imm16");
4808: M_CALL_CC( op_base|0xec );
4809: end_opcode("z_op");
4810:
4811: beg_opcode(10,s(op,0xf4),"CALL P,imm16");
4812: M_CALL_CC( op_base|0xf4 );
4813: end_opcode("z_op");
4814:
4815: beg_opcode(10,s(op,0xfc),"CALL M,imm16");
4816: M_CALL_CC( op_base|0xfc );
4817: end_opcode("z_op");
4818:
4819: /*********/
4820:
4821: beg_opcode(10,s(op,0xc9),"RET");
4822: M_RET( op_base|0xc9 );
4823: end_opcode("z_op");
4824:
4825: beg_opcode( 4,s(op,0xd9),"EXX");
4826: M_EXX();
4827: end_opcode("z_op");
4828:
4829: beg_opcode( 4,s(op,0xe9),"JP (%s)",hl);
4830: M_JP_REG( op_base|0xe9, zhl32 );
4831: end_opcode("z_op");
4832:
4833: beg_opcode( 6,s(op,0xf9),"LD SP,%s",hl);
4834: I(0,movl, ECX, zhl32, 0);
4835: I(0,movl, zSP32, ECX, 0);
4836: end_opcode("z_op");
4837:
4838: beg_opcode(17,s(op,0xcd),"CALL imm16");
4839: M_CALL( op_base|0xcd );
4840: end_opcode("z_op");
4841:
4842: beg_opcode( 4,s(op,0xdd),"DD xx");
4843: end_opcode("z_dd");
4844:
4845: beg_opcode( 0,s(op,0xed),"ED xx");
4846: end_opcode("z_ed");
4847:
4848: beg_opcode( 4,s(op,0xfd),"FD xx");
4849: end_opcode("z_fd");
4850:
4851: /*********/
4852:
4853: beg_opcode( 7,s(op,0xc6),"ADD A,imm8");
4854: ARG( DL );
4855: M_ADD( DL );
4856: end_opcode("z_op");
4857:
4858: beg_opcode( 7,s(op,0xce),"ADC A,imm8");
4859: ARG( DL );
4860: M_ADC( DL );
4861: end_opcode("z_op");
4862:
4863: beg_opcode( 7,s(op,0xd6),"SUB imm8");
4864: ARG( DL );
4865: M_SUB( DL );
4866: end_opcode("z_op");
4867:
4868: beg_opcode( 7,s(op,0xde),"SBC A,imm8");
4869: ARG( DL );
4870: M_SBC( DL );
4871: end_opcode("z_op");
4872:
4873: beg_opcode( 7,s(op,0xe6),"AND imm8");
4874: ARG( DL );
4875: M_AND( DL );
4876: end_opcode("z_op");
4877:
4878: beg_opcode( 7,s(op,0xee),"XOR imm8");
4879: ARG( DL );
4880: M_XOR( DL );
4881: end_opcode("z_op");
4882:
4883: beg_opcode( 7,s(op,0xf6),"OR imm8");
4884: ARG( DL );
4885: M_OR( DL );
4886: end_opcode("z_op");
4887:
4888: beg_opcode( 7,s(op,0xfe),"CP imm8");
4889: ARG( DL );
4890: M_CP( DL );
4891: end_opcode("z_op");
4892:
4893: /*********/
4894:
4895: beg_opcode(11,s(op,0xc7),"RST $00");
4896: M_RST( op_base|0xc7 );
4897: end_opcode("z_op");
4898:
4899: beg_opcode(11,s(op,0xcf),"RST $08");
4900: M_RST( op_base|0xcf );
4901: end_opcode("z_op");
4902:
4903: beg_opcode(11,s(op,0xd7),"RST $10");
4904: M_RST( op_base|0xd7 );
4905: end_opcode("z_op");
4906:
4907: beg_opcode(11,s(op,0xdf),"RST $18");
4908: M_RST( op_base|0xdf );
4909: end_opcode("z_op");
4910:
4911: beg_opcode(11,s(op,0xe7),"RST $20");
4912: M_RST( op_base|0xe7 );
4913: end_opcode("z_op");
4914:
4915: beg_opcode(11,s(op,0xef),"RST $28");
4916: M_RST( op_base|0xef );
4917: end_opcode("z_op");
4918:
4919: beg_opcode(11,s(op,0xf7),"RST $30");
4920: M_RST( op_base|0xf7 );
4921: end_opcode("z_op");
4922:
4923: beg_opcode(11,s(op,0xff),"RST $38");
4924: M_RST( op_base|0xff );
4925: end_opcode("z_op");
4926: }
4927:
4928: void mk_opcodes_cb(void)
4929: {
4930: int i, j, b;
4931: char r[4+1], zr[32+1];
4932: for (i = 0; i < 0x100; i += 0x08) {
4933: for (j = 0; j < 8; j++) {
4934: switch (j) {
4935: case 0: strcpy(r,"B"); strcpy(zr,zB); break;
4936: case 1: strcpy(r,"C"); strcpy(zr,zC); break;
4937: case 2: strcpy(r,"D"); strcpy(zr,zD); break;
4938: case 3: strcpy(r,"E"); strcpy(zr,zE); break;
4939: case 4: strcpy(r,"H"); strcpy(zr,H); break;
4940: case 5: strcpy(r,"L"); strcpy(zr,L); break;
4941: case 6: strcpy(r,"(HL)"); strcpy(zr,DL); break;
4942: case 7: strcpy(r,"A"); strcpy(zr,A); break;
4943: }
4944: switch (i) {
4945: case 0x00:
4946: if (j == 6) {
4947: beg_opcode(15,s("cb_%02x",i+j),"RLC %s",r);
4948: RBYTE( 2, EDX, HL32 );
4949: } else {
4950: beg_opcode( 8,s("cb_%02x",i+j),"RLC %s",r);
4951: }
4952: M_RLC( zr );
4953: if (j == 6) WBYTE( 2, HL32, EDX );
4954: end_opcode("z_op");
4955: break;
4956: case 0x08:
4957: if (j == 6) {
4958: beg_opcode(15,s("cb_%02x",i+j),"RRC %s",r);
4959: RBYTE( 2, EDX, HL32 );
4960: } else {
4961: beg_opcode( 8,s("cb_%02x",i+j),"RRC %s",r);
4962: }
4963: M_RRC( zr );
4964: if (j == 6) WBYTE( 2, HL32, EDX );
4965: end_opcode("z_op");
4966: break;
4967: case 0x10:
4968: if (j == 6) {
4969: beg_opcode(15,s("cb_%02x",i+j),"RL %s",r);
4970: RBYTE( 2, EDX, HL32 );
4971: } else {
4972: beg_opcode( 8,s("cb_%02x",i+j),"RL %s",r);
4973: }
4974: M_RL ( zr );
4975: if (j == 6) WBYTE( 2, HL32, EDX );
4976: end_opcode("z_op");
4977: break;
4978: case 0x18:
4979: if (j == 6) {
4980: beg_opcode(15,s("cb_%02x",i+j),"RR %s",r);
4981: RBYTE( 2, EDX, HL32 );
4982: } else {
4983: beg_opcode( 8,s("cb_%02x",i+j),"RR %s",r);
4984: }
4985: M_RR ( zr );
4986: if (j == 6) WBYTE( 2, HL32, EDX );
4987: end_opcode("z_op");
4988: break;
4989: case 0x20:
4990: if (j == 6) {
4991: beg_opcode(15,s("cb_%02x",i+j),"SLA %s",r);
4992: RBYTE( 2, EDX, HL32 );
4993: } else {
4994: beg_opcode( 8,s("cb_%02x",i+j),"SLA %s",r);
4995: }
4996: M_SLA( zr );
4997: if (j == 6) WBYTE( 2, HL32, EDX );
4998: end_opcode("z_op");
4999: break;
5000: case 0x28:
5001: if (j == 6) {
5002: beg_opcode(15,s("cb_%02x",i+j),"SRA %s",r);
5003: RBYTE( 2, EDX, HL32 );
5004: } else {
5005: beg_opcode( 8,s("cb_%02x",i+j),"SRA %s",r);
5006: }
5007: M_SRA( zr );
5008: if (j == 6) WBYTE( 2, HL32, EDX );
5009: end_opcode("z_op");
5010: break;
5011: case 0x30:
5012: if (j == 6) {
5013: beg_opcode(15,s("cb_%02x",i+j),"SLL %s",r);
5014: RBYTE( 2, EDX, HL32 );
5015: } else {
5016: beg_opcode( 8,s("cb_%02x",i+j),"SLL %s",r);
5017: }
5018: M_SLL( zr );
5019: if (j == 6) WBYTE( 2, HL32, EDX );
5020: end_opcode("z_op");
5021: break;
5022: case 0x38:
5023: if (j == 6) {
5024: beg_opcode(15,s("cb_%02x",i+j),"SRL %s",r);
5025: RBYTE( 2, EDX, HL32 );
5026: } else {
5027: beg_opcode( 8,s("cb_%02x",i+j),"SRL %s",r);
5028: }
5029: M_SRL( zr );
5030: if (j == 6) WBYTE( 2, HL32, EDX );
5031: end_opcode("z_op");
5032: break;
5033: case 0x40: case 0x48: case 0x50: case 0x58:
5034: case 0x60: case 0x68: case 0x70: case 0x78:
5035: b = (i >> 3) & 7;
5036: if (j == 6) {
5037: beg_opcode(12,s("cb_%02x",i+j),"BIT %d,%s",b,r);
5038: RBYTE( 2, EDX, HL32 );
5039: } else {
5040: beg_opcode( 8,s("cb_%02x",i+j),"BIT %d,%s",b,r);
5041: }
5042: M_BIT( b, zr );
5043: end_opcode("z_op");
5044: break;
5045: case 0x80: case 0x88: case 0x90: case 0x98:
5046: case 0xa0: case 0xa8: case 0xb0: case 0xb8:
5047: b = (i >> 3) & 7;
5048: if (j == 6) {
5049: beg_opcode(15,s("cb_%02x",i+j),"RES %d,%s",b,r);
5050: RBYTE( 2, EDX, HL32 );
5051: } else {
5052: beg_opcode( 8,s("cb_%02x",i+j),"RES %d,%s",b,r);
5053: }
5054: M_RES( b, zr );
5055: if (j == 6) WBYTE( 2, HL32, EDX );
5056: end_opcode("z_op");
5057: break;
5058: case 0xc0: case 0xc8: case 0xd0: case 0xd8:
5059: case 0xe0: case 0xe8: case 0xf0: case 0xf8:
5060: b = (i >> 3) & 7;
5061: if (j == 6) {
5062: beg_opcode(15,s("cb_%02x",i+j),"SET %d,%s",b,r);
5063: RBYTE( 2, EDX, HL32 );
5064: } else {
5065: beg_opcode( 8,s("cb_%02x",i+j),"SET %d,%s",b,r);
5066: }
5067: M_SET( b, zr );
5068: if (j == 6) WBYTE( 2, HL32, EDX );
5069: end_opcode("z_op");
5070: break;
5071: }
5072: }
5073: }
5074: }
5075:
5076: void mk_opcodes_xx(void)
5077: {
5078: int i, j, b;
5079: char r[32+1], zr[32+1];
5080: for (i = 0; i < 0x100; i += 0x08) {
5081: for (j = 0; j < 8; j++) {
5082: switch (j) {
5083: case 0: strcpy(r,"B=(IX/IY+ofs8)"); strcpy(zr,zB); break;
5084: case 1: strcpy(r,"C=(IX/IY+ofs8)"); strcpy(zr,zC); break;
5085: case 2: strcpy(r,"D=(IX/IY+ofs8)"); strcpy(zr,zD); break;
5086: case 3: strcpy(r,"E=(IX/IY+ofs8)"); strcpy(zr,zE); break;
5087: case 4: strcpy(r,"H=(IX/IY+ofs8)"); strcpy(zr,H); break;
5088: case 5: strcpy(r,"L=(IX/IY+ofs8)"); strcpy(zr,L); break;
5089: case 6: strcpy(r,"(IX/IY+ofs8)"); strcpy(zr,DL); break;
5090: case 7: strcpy(r,"A=(IX/IY+ofs8)"); strcpy(zr,A); break;
5091: }
5092: switch (i) {
5093: case 0x00:
5094: beg_opcode(19,s("xx_%02x",i+j),"RLC %s",r);
5095: M_RLC( DL );
5096: if (j != 6) I(0,movb, zr, DL, 0);
5097: #if WB_EA4_EDX
5098: I(0,jmp, "wb_ea4_edx",0, 0);
5099: #else
5100: WBYTE( 4, EBP, EDX );
5101: end_opcode("z_op");
5102: #endif
5103: break;
5104: case 0x08:
5105: beg_opcode(19,s("xx_%02x",i+j),"RRC %s",r);
5106: M_RRC( DL );
5107: if (j != 6) I(0,movb, zr, DL, 0);
5108: #if WB_EA4_EDX
5109: I(0,jmp, "wb_ea4_edx",0, 0);
5110: #else
5111: WBYTE( 4, EBP, EDX );
5112: end_opcode("z_op");
5113: #endif
5114: break;
5115: case 0x10:
5116: beg_opcode(19,s("xx_%02x",i+j),"RL %s",r);
5117: M_RL ( DL );
5118: if (j != 6) I(0,movb, zr, DL, 0);
5119: #if WB_EA4_EDX
5120: I(0,jmp, "wb_ea4_edx",0, 0);
5121: #else
5122: WBYTE( 4, EBP, EDX );
5123: end_opcode("z_op");
5124: #endif
5125: break;
5126: case 0x18:
5127: beg_opcode(19,s("xx_%02x",i+j),"RR %s",r);
5128: M_RR ( DL );
5129: if (j != 6) I(0,movb, zr, DL, 0);
5130: #if WB_EA4_EDX
5131: I(0,jmp, "wb_ea4_edx",0, 0);
5132: #else
5133: WBYTE( 4, EBP, EDX );
5134: end_opcode("z_op");
5135: #endif
5136: break;
5137: case 0x20:
5138: beg_opcode(19,s("xx_%02x",i+j),"SLA %s",r);
5139: M_SLA( DL );
5140: if (j != 6) I(0,movb, zr, DL, 0);
5141: #if WB_EA4_EDX
5142: I(0,jmp, "wb_ea4_edx",0, 0);
5143: #else
5144: WBYTE( 4, EBP, EDX );
5145: end_opcode("z_op");
5146: #endif
5147: break;
5148: case 0x28:
5149: beg_opcode(19,s("xx_%02x",i+j),"SRA %s",r);
5150: M_SRA( DL );
5151: if (j != 6) I(0,movb, zr, DL, 0);
5152: #if WB_EA4_EDX
5153: I(0,jmp, "wb_ea4_edx",0, 0);
5154: #else
5155: WBYTE( 4, EBP, EDX );
5156: end_opcode("z_op");
5157: #endif
5158: break;
5159: case 0x30:
5160: beg_opcode(19,s("xx_%02x",i+j),"SLL %s",r);
5161: M_SLL( DL );
5162: if (j != 6) I(0,movb, zr, DL, 0);
5163: #if WB_EA4_EDX
5164: I(0,jmp, "wb_ea4_edx",0, 0);
5165: #else
5166: WBYTE( 4, EBP, EDX );
5167: end_opcode("z_op");
5168: #endif
5169: break;
5170: case 0x38:
5171: beg_opcode(19,s("xx_%02x",i+j),"SRL %s",r);
5172: M_SRL( DL );
5173: if (j != 6) I(0,movb, zr, DL, 0);
5174: #if WB_EA4_EDX
5175: I(0,jmp, "wb_ea4_edx",0, 0);
5176: #else
5177: WBYTE( 4, EBP, EDX );
5178: end_opcode("z_op");
5179: #endif
5180: break;
5181: case 0x40: case 0x48: case 0x50: case 0x58:
5182: case 0x60: case 0x68: case 0x70: case 0x78:
5183: b = (i >> 3) & 7;
5184: beg_opcode(16,s("xx_%02x",i+j),"BIT %d,%s",b,r);
5185: M_BIT( b, DL );
5186: end_opcode("z_op");
5187: break;
5188: case 0x80: case 0x88: case 0x90: case 0x98:
5189: case 0xa0: case 0xa8: case 0xb0: case 0xb8:
5190: b = (i >> 3) & 7;
5191: beg_opcode(19,s("xx_%02x",i+j),"RES %d,%s",b,r);
5192: M_RES( b, DL );
5193: if (j != 6) I(0,movb, zr, DL, 0);
5194: #if WB_EA4_EDX
5195: I(0,jmp, "wb_ea4_edx",0, 0);
5196: #else
5197: WBYTE( 4, EBP, EDX );
5198: end_opcode("z_op");
5199: #endif
5200: break;
5201: case 0xc0: case 0xc8: case 0xd0: case 0xd8:
5202: case 0xe0: case 0xe8: case 0xf0: case 0xf8:
5203: b = (i >> 3) & 7;
5204: beg_opcode(19,s("xx_%02x",i+j),"SET %d,%s",b,r);
5205: M_SET( b, DL );
5206: if (j != 6) I(0,movb, zr, DL, 0);
5207: #if WB_EA4_EDX
5208: I(0,jmp, "wb_ea4_edx",0, 0);
5209: #else
5210: WBYTE( 4, EBP, EDX );
5211: end_opcode("z_op");
5212: #endif
5213: break;
5214: }
5215: }
5216: }
5217: }
5218:
5219: void mk_opcodes_ed(void)
5220: {
5221: beg_opcode(12,"ed_40","IN B,(C)");
5222: M_IN_BC( zB );
5223: end_opcode("z_op");
5224:
5225: beg_opcode(12,"ed_41","OUT (C),B");
5226: M_OUT_BC( zB );
5227: end_opcode("z_op");
5228:
5229: beg_opcode(15,"ed_42","SBC HL,BC");
5230: M_SBC16( zBC );
5231: end_opcode("z_op");
5232:
5233: beg_opcode(20,"ed_43","LD (imm16),BC");
5234: ARG16( ECX );
5235: WWORD( 4, ECX, zBC32 );
5236: end_opcode("z_op");
5237:
5238: beg_opcode( 8,"ed_44","NEG");
5239: M_NEG();
5240: end_opcode("z_op");
5241:
5242: beg_opcode(14,"ed_45","RETN");
5243: M_RETN( 0x45 );
5244: end_opcode("z_op");
5245:
5246: beg_opcode( 8,"ed_46","IM 0");
5247: I(0,movb, zIM, D(0), "set IM = 0");
5248: end_opcode("z_op");
5249:
5250: beg_opcode( 9,"ed_47","LD I,A");
5251: M_LD_I_A();
5252: end_opcode("z_op");
5253:
5254: beg_opcode(12,"ed_48","IN C,(C)");
5255: M_IN_BC( zC );
5256: end_opcode("z_op");
5257:
5258: beg_opcode(12,"ed_49","OUT (C),C");
5259: M_OUT_BC( zC );
5260: end_opcode("z_op");
5261:
5262: beg_opcode(15,"ed_4a","ADC HL,BC");
5263: M_ADC16( zBC );
5264: end_opcode("z_op");
5265:
5266: beg_opcode(20,"ed_4b","LD BC,(imm16)");
5267: ARG16( ECX );
5268: RWORD( 4, EDX, ECX );
5269: I(0,movw, zBC, DX, 0);
5270: end_opcode("z_op");
5271:
5272: beg_opcode( 8,"ed_4c","NEG");
5273: M_NEG();
5274: end_opcode("z_op");
5275:
5276: beg_opcode(14,"ed_4d","RETI");
5277: M_RETI(0x4d);
5278: end_opcode("z_op");
5279:
5280: beg_opcode( 8,"ed_4e","IM 0");
5281: I(0,movb, zIM, D(0), "set IM = 0");
5282: end_opcode("z_op");
5283:
5284: beg_opcode( 9,"ed_4f","LD R,A");
5285: M_LD_R_A();
5286: end_opcode("z_op");
5287:
5288: beg_opcode(12,"ed_50","IN D,(C)");
5289: M_IN_BC( zD );
5290: end_opcode("z_op");
5291:
5292: beg_opcode(12,"ed_51","OUT (C),D");
5293: M_OUT_BC( zD );
5294: end_opcode("z_op");
5295:
5296: beg_opcode(15,"ed_52","SBC HL,DE");
5297: M_SBC16( zDE );
5298: end_opcode("z_op");
5299:
5300: beg_opcode(20,"ed_53","LD (imm16),DE");
5301: ARG16( ECX );
5302: WWORD( 4, ECX, zDE32 );
5303: end_opcode("z_op");
5304:
5305: beg_opcode( 8,"ed_54","NEG");
5306: M_NEG();
5307: end_opcode("z_op");
5308:
5309: beg_opcode(14,"ed_55","RETN");
5310: M_RETN( 0x55 );
5311: end_opcode("z_op");
5312:
5313: beg_opcode( 8,"ed_56","IM 1");
5314: I(0,movb, zIM, D(1), "set IM = 1");
5315: end_opcode("z_op");
5316:
5317: beg_opcode( 9,"ed_57","LD A,I");
5318: M_LD_A_I();
5319: end_opcode("z_op");
5320:
5321: beg_opcode(12,"ed_58","IN E,(C)");
5322: M_IN_BC( zE );
5323: end_opcode("z_op");
5324:
5325: beg_opcode(12,"ed_59","OUT (C),E");
5326: M_OUT_BC( zE );
5327: end_opcode("z_op");
5328:
5329: beg_opcode(15,"ed_5a","ADC HL,DE");
5330: M_ADC16( zDE );
5331: end_opcode("z_op");
5332:
5333: beg_opcode(20,"ed_5b","LD DE,(imm16)");
5334: ARG16( ECX );
5335: RWORD( 4, EDX, ECX );
5336: I(0,movw, zDE, DX, 0);
5337: end_opcode("z_op");
5338:
5339: beg_opcode( 8,"ed_5c","NEG");
5340: M_NEG();
5341: end_opcode("z_op");
5342:
5343: beg_opcode(14,"ed_5d","RETI");
5344: M_RETI( 0x5d );
5345: end_opcode("z_op");
5346:
5347: beg_opcode( 8,"ed_5e","IM 2");
5348: I(0,movb, zIM, D(2), "set IM = 2");
5349: end_opcode("z_op");
5350:
5351: beg_opcode( 9,"ed_5f","LD A,R");
5352: M_LD_A_R();
5353: end_opcode("z_op");
5354:
5355: beg_opcode(12,"ed_60","IN H,(C)");
5356: M_IN_BC( H );
5357: end_opcode("z_op");
5358:
5359: beg_opcode(12,"ed_61","OUT (C),H");
5360: M_OUT_BC( H );
5361: end_opcode("z_op");
5362:
5363: beg_opcode(15,"ed_62","SBC HL,HL");
5364: M_SBC16( HL );
5365: end_opcode("z_op");
5366:
5367: beg_opcode(20,"ed_63","LD (imm16),HL");
5368: ARG16( ECX );
5369: WWORD( 4, ECX, HL32 );
5370: end_opcode("z_op");
5371:
5372: beg_opcode( 8,"ed_64","NEG");
5373: M_NEG();
5374: end_opcode("z_op");
5375:
5376: beg_opcode(14,"ed_65","RETN");
5377: M_RETN( 0x65 );
5378: end_opcode("z_op");
5379:
5380: beg_opcode( 8,"ed_66","IM 0");
5381: I(0,movb, zIM, D(0), "set IM = 0");
5382: end_opcode("z_op");
5383:
5384: beg_opcode(18,"ed_67","RRD (HL)");
5385: M_RRD();
5386: end_opcode("z_op");
5387:
5388: beg_opcode(12,"ed_68","IN L,(C)");
5389: M_IN_BC( L );
5390: end_opcode("z_op");
5391:
5392: beg_opcode(12,"ed_69","OUT (C),L");
5393: M_OUT_BC( L );
5394: end_opcode("z_op");
5395:
5396: beg_opcode(15,"ed_6a","ADC HL,HL");
5397: M_ADC16( HL );
5398: end_opcode("z_op");
5399:
5400: beg_opcode(20,"ed_6b","LD HL,(imm16)");
5401: ARG16( ECX );
5402: RWORD( 4, EDX, ECX );
5403: I(0,movw, HL, DX, 0);
5404: end_opcode("z_op");
5405:
5406: beg_opcode( 8,"ed_6c","NEG");
5407: M_NEG();
5408: end_opcode("z_op");
5409:
5410: beg_opcode(14,"ed_6d","RETI");
5411: M_RETI( 0x6d );
5412: end_opcode("z_op");
5413:
5414: beg_opcode( 8,"ed_6e","IM 0");
5415: I(0,movb, zIM, D(0), "set IM = 0");
5416: end_opcode("z_op");
5417:
5418: beg_opcode(18,"ed_6f","RLD (HL)");
5419: M_RLD();
5420: end_opcode("z_op");
5421:
5422: beg_opcode(12,"ed_70","IN F,(C)");
5423: M_IN_BC( DL );
5424: end_opcode("z_op");
5425:
5426: beg_opcode(12,"ed_71","OUT (C),0");
5427: I(0,movb, DL, D(0), 0);
5428: M_OUT_BC( DL );
5429: end_opcode("z_op");
5430:
5431: beg_opcode(15,"ed_72","SBC HL,SP");
5432: M_SBC16( zSP );
5433: end_opcode("z_op");
5434:
5435: beg_opcode(20,"ed_73","LD (imm16),SP");
5436: ARG16( ECX );
5437: WWORD( 4, ECX, zSP32 );
5438: end_opcode("z_op");
5439:
5440: beg_opcode( 8,"ed_74","NEG");
5441: M_NEG();
5442: end_opcode("z_op");
5443:
5444: beg_opcode(14,"ed_75","RETN");
5445: M_RETN( 0x75 );
5446: end_opcode("z_op");
5447:
5448: beg_opcode( 8,"ed_76","IM 1");
5449: I(0,movb, zIM, D(1), "set IM = 1");
5450: end_opcode("z_op");
5451:
5452: beg_opcode(12,"ed_78","IN A,(C)");
5453: M_IN_BC( A );
5454: end_opcode("z_op");
5455:
5456: beg_opcode(12,"ed_79","OUT (C),A");
5457: M_OUT_BC( A );
5458: end_opcode("z_op");
5459:
5460: beg_opcode(15,"ed_7a","ADC HL,SP");
5461: M_ADC16( zSP );
5462: end_opcode("z_op");
5463:
5464: beg_opcode(20,"ed_7b","LD SP,(imm16)");
5465: ARG16( ECX );
5466: RWORD( 4, EDX, ECX );
5467: I(0,movw, zSP, DX, 0);
5468: end_opcode("z_op");
5469:
5470: beg_opcode( 8,"ed_7c","NEG");
5471: M_NEG();
5472: end_opcode("z_op");
5473:
5474: beg_opcode(14,"ed_7d","RETI");
5475: M_RETI( 0x7d );
5476: end_opcode("z_op");
5477:
5478: beg_opcode( 8,"ed_7e","IM 2");
5479: I(0,movb, zIM, D(2), "set IM = 2");
5480: end_opcode("z_op");
5481:
5482: beg_opcode(16,"ed_a0","LDI");
5483: RBYTE( 2, EDX, HL32 );
5484: WBYTE( 2, zDE32, EDX );
5485: I(0,andb, F, X(SF|ZF|CF), "keep S,Z and C flags");
5486: I(0,incw, HL, 0, "HL++");
5487: I(0,incw, zDE, 0, "DE++");
5488: I(0,decw, zBC, 0, "BC--");
5489: I(0,je, LS("ed_a0_skip"),0, 0);
5490: I(0,orb, F, X(PF), "BC not zero, set P/V");
5491: S("ed_a0_skip",0);
5492: end_opcode("z_op");
5493:
5494: beg_opcode(16,"ed_a1","CPI");
5495: RBYTE( 2, EDX, HL32 );
5496: I(0,movb, CL, F, "save flags");
5497: I(0,andb, CL, X(CF), "keep C flag");
5498: I(0,cmpb, A, DL, 0);
5499: I(0,lahf, 0, 0, 0);
5500: I(0,andb, F, X(SF|ZF|HF), "mask S,Z and H flags");
5501: I(0,orb, F, X(NF), "set N flag");
5502: I(0,orb, F, CL, "combine with C");
5503: I(0,incw, HL, 0, "HL++");
5504: I(0,decw, zBC, 0, "BC--");
5505: I(0,je, LS("ed_a1_skip"),0, 0);
5506: I(0,orb, F, X(PF), "BC not zero, set P/V");
5507: S("ed_a1_skip",0);
5508: end_opcode("z_op");
5509:
5510: beg_opcode(16,"ed_a2","INI");
5511: I(0,decb, zB, 0, "--B");
5512: M_IN( 2, EDX, zBC32 );
5513: WBYTE( 2, HL32, EDX );
5514: I(0,movb, F, X(ZF|NF), "set Z and N flags");
5515: I(0,incw, HL, 0, "HL++");
5516: I(0,testb, zB, B(-1), "B counted down?");
5517: I(0,je, LS("ed_a2_skip"),0, 0);
5518: I(0,movb, F, X(NF), "set N only");
5519: S("ed_a2_skip",0);
5520: end_opcode("z_op");
5521:
5522: beg_opcode(16,"ed_a3","OUTI");
5523: RBYTE( 2, EDX, HL32 );
5524: M_OUT( 2, zBC32, EDX );
5525: I(0,movb, F, X(ZF|NF), "set Z and N");
5526: I(0,incw, HL, 0, "HL++");
5527: I(0,decb, zB, 0, "B--");
5528: I(0,je, LS("ed_a3_skip"),0, 0);
5529: I(0,movb, F, X(NF), "set N only");
5530: S("ed_a3_skip",0);
5531: end_opcode("z_op");
5532:
5533: beg_opcode(16,"ed_a8","LDD");
5534: RBYTE( 2, EDX, HL32 );
5535: WBYTE( 2, zDE32, EDX );
5536: I(0,andb, F, X(SF|ZF|CF), "keep S,Z and C flags");
5537: I(0,decw, HL, 0, "HL--");
5538: I(0,decw, zDE, 0, "DE--");
5539: I(0,decw, zBC, 0, "BC--");
5540: I(0,je, LS("ed_a8_skip"),0, 0);
5541: I(0,orb, F, X(PF), "BC not zero, set P/V");
5542: S("ed_a8_skip",0);
5543: end_opcode("z_op");
5544:
5545: beg_opcode(16,"ed_a9","CPD");
5546: RBYTE( 2, EDX, HL32 );
5547: I(0,movb, CL, F, "save flags");
5548: I(0,andb, CL, X(CF), "keep C flag");
5549: I(0,cmpb, A, DL, 0);
5550: I(0,lahf, 0, 0, 0);
5551: I(0,andb, F, X(SF|ZF|HF), "mask S,Z and H flags");
5552: I(0,orb, F, X(NF), "set N flag");
5553: I(0,orb, F, CL, "combine with C");
5554: I(0,decw, HL, 0, "HL--");
5555: I(0,decw, zBC, 0, "BC--");
5556: I(0,je, LS("ed_a9_skip"),0, 0);
5557: I(0,orb, F, X(PF), "BC not zero, set P/V");
5558: S("ed_a9_skip",0);
5559: end_opcode("z_op");
5560:
5561: beg_opcode(16,"ed_aa","IND");
5562: I(0,decb, zB, 0, "--B");
5563: M_IN( 2, EDX, zBC32 );
5564: WBYTE( 2, HL32, EDX );
5565: I(0,movb, F, X(ZF|NF), "set Z and N flags");
5566: I(0,decw, HL, 0, "HL--");
5567: I(0,testb, zB, B(-1), "B counted down?");
5568: I(0,je, LS("ed_aa_skip"),0, 0);
5569: I(0,andb, F, X(NF), "leave N only");
5570: S("ed_aa_skip",0);
5571: end_opcode("z_op");
5572:
5573: beg_opcode(16,"ed_ab","OUTD");
5574: RBYTE( 2, EDX, HL32 );
5575: M_OUT( 2, zBC32, EDX );
5576: I(0,movb, F, X(ZF|NF), "set Z and N flags");
5577: I(0,decw, HL, 0, "HL--");
5578: I(0,decb, zB, 0, "B--");
5579: I(0,je, LS("ed_ab_skip"),0, 0);
5580: I(0,andb, F, X(NF), "set N only");
5581: S("ed_ab_skip",0);
5582: end_opcode("z_op");
5583:
5584: beg_opcode(16,"ed_b0","LDIR");
5585: RBYTE( 2, EDX, HL32 );
5586: WBYTE( 2, zDE32, EDX );
5587: I(0,andb, F, X(SF|ZF|CF), "keep S,Z and C flags");
5588: I(0,incw, HL, 0, "HL++");
5589: I(0,incw, zDE, 0, "DE++");
5590: I(0,decw, zBC, 0, "BC--");
5591: I(0,je, LS("ed_b0_skip"),0, 0);
5592: I(0,orb, F, X(PF), "BC not zero, set P/V");
5593: ADJUST_PC(-2);
5594: I(0,subl, zICOUNT,B(5), "five more cycles");
5595: S("ed_b0_skip",0);
5596: end_opcode("z_op");
5597:
5598: beg_opcode(16,"ed_b1","CPIR");
5599: RBYTE( 2, EDX, HL32 );
5600: I(0,movb, CL, F, "save flags");
5601: I(0,andb, CL, X(CF), "keep C flag");
5602: I(0,cmpb, A, DL, 0);
5603: I(0,lahf, 0, 0, 0);
5604: I(0,andb, F, X(SF|ZF|HF), "mask S,Z and H flags");
5605: I(0,orb, F, X(NF), "set N flag");
5606: I(0,orb, F, CL, "combine with C");
5607: I(0,incw, HL, 0, "HL++");
5608: I(0,decw, zBC, 0, "BC--");
5609: I(0,je, LS("ed_b1_skip"),0, 0);
5610: I(0,orb, F, X(PF), "BC not zero, set P/V");
5611: I(0,testb, F, X(ZF), "Z flag set?");
5612: I(0,jne, LS("ed_b1_skip"),0, "yes, don't repeat");
5613: ADJUST_PC(-2);
5614: I(0,subl, zICOUNT,B(5), "five more cycles");
5615: S("ed_b1_skip",0);
5616: end_opcode("z_op");
5617:
5618: beg_opcode(16,"ed_b2","INIR");
5619: I(0,decb, zB, 0, "--B");
5620: M_IN( 2, EDX, zBC32 );
5621: WBYTE( 2, HL32, EDX );
5622: I(0,incw, HL, 0, "HL++");
5623: I(0,movb, F, X(ZF|NF), "set Z and N");
5624: I(0,testb, zB, B(-1), "B counted down?");
5625: I(0,je, LS("ed_b2_skip"),0, 0);
5626: I(0,movb, F, X(NF), "set N only");
5627: ADJUST_PC(-2);
5628: I(0,subl, zICOUNT,B(5), "five more cycles");
5629: S("ed_b2_skip",0);
5630: end_opcode("z_op");
5631:
5632: beg_opcode(16,"ed_b3","OTIR");
5633: RBYTE( 2, EDX, HL32 );
5634: M_OUT( 2, zBC32, EDX );
5635: I(0,movb, F, X(ZF|NF), "set Z and N");
5636: I(0,incw, HL, 0, "HL++");
5637: I(0,decb, zB, 0, "B--");
5638: I(0,je, LS("ed_b3_skip"),0, 0);
5639: I(0,movb, F, X(NF), "set N only");
5640: ADJUST_PC(-2);
5641: I(0,subl, zICOUNT,B(5), "five more cycles");
5642: S("ed_b3_skip",0);
5643: end_opcode("z_op");
5644:
5645: beg_opcode(16,"ed_b8","LDDR");
5646: RBYTE( 2, EDX, HL32 );
5647: WBYTE( 2, zDE32, EDX );
5648: I(0,andb, F, X(SF|ZF|CF), "keep S,Z and C flags");
5649: I(0,decw, HL, 0, "HL--");
5650: I(0,decw, zDE, 0, "DE--");
5651: I(0,decw, zBC, 0, "BC--");
5652: I(0,je, LS("ed_b8_skip"),0, 0);
5653: I(0,orb, F, X(PF), "BC not zero, set P/V");
5654: ADJUST_PC(-2);
5655: I(0,subl, zICOUNT,B(5), "five more cycles");
5656: S("ed_b8_skip",0);
5657: end_opcode("z_op");
5658:
5659: beg_opcode(16,"ed_b9","CPDR");
5660: RBYTE( 2, EDX, HL32 );
5661: I(0,movb, CL, F, "save flags");
5662: I(0,andb, CL, X(CF), "keep C flag");
5663: I(0,cmpb, A, DL, 0);
5664: I(0,lahf, 0, 0, 0);
5665: I(0,andb, F, X(SF|ZF|HF), "mask S,Z and H flags");
5666: I(0,orb, F, X(NF), "set N flag");
5667: I(0,orb, F, CL, "combine with C");
5668: I(0,decw, HL, 0, "HL--");
5669: I(0,decw, zBC, 0, "BC--");
5670: I(0,je, LS("ed_b9_skip"),0, 0);
5671: I(0,orb, F, X(PF), "BC not zero, set P/V");
5672: I(0,testb, F, X(ZF), "Z flag set?");
5673: I(0,jne, LS("ed_b9_skip"),0, "yes, don't repeat");
5674: ADJUST_PC(-2);
5675: I(0,subl, zICOUNT,B(5), "five more cycles");
5676: S("ed_b9_skip",0);
5677: end_opcode("z_op");
5678:
5679: beg_opcode(16,"ed_ba","INDR");
5680: I(0,decb, zB, 0, "--B");
5681: M_IN( 2, EDX, zBC32 );
5682: WBYTE( 2, HL32, EDX );
5683: I(0,movb, F, X(ZF|NF), "set Z and N");
5684: I(0,decw, HL, 0, "HL--");
5685: I(0,testb, zB, B(-1), 0);
5686: I(0,je, LS("ed_ba_skip"),0, 0);
5687: I(0,movb, F, X(NF), "set N only");
5688: ADJUST_PC(-2);
5689: I(0,subl, zICOUNT,B(5), "five more cycles");
5690: S("ed_ba_skip",0);
5691: end_opcode("z_op");
5692:
5693: beg_opcode(16,"ed_bb","OTDR");
5694: RBYTE( 2, EDX, HL32 );
5695: M_OUT( 2, zBC32, EDX );
5696: I(0,movb, F, X(ZF|NF), "set Z and N");
5697: I(0,decw, HL, 0, "HL--");
5698: I(0,decb, zB, 0, "B--");
5699: I(0,je, LS("ed_bb_skip"),0, 0);
5700: I(0,movb, F, X(NF), "set N only");
5701: ADJUST_PC(-2);
5702: I(0,subl, zICOUNT,B(5), "five more cycles");
5703: S("ed_bb_skip",0);
5704: end_opcode("z_op");
5705: }
5706:
5707: int main(int ac, char **av)
5708: {
5709: int i;
5710:
5711: if (ac < 2) {
5712: fprintf(stderr, "usage: %s [options] output.asm\n", av[0]);
5713: fprintf(stderr, "options can be one of the following\n");
5714: fprintf(stderr, "-nasm\tgenerate NASM output%s\n",(as==NASM)?" (default)":"");
5715: fprintf(stderr, "-gas\tgenerate GNU assembler output%s\n",(as==GAS)?" (default)":"");
5716: fprintf(stderr, "-verbose n\toutput error.log (n= 0 none - 9 everything)\n");
5717: fprintf(stderr, "-On\temit self optimizing code (n=0 no, n=1 yes)\n");
5718: fprintf(stderr, "-Ddefine\tdefines for conditional output\n");
5719: fprintf(stderr, "\t-DMAME_DEBUG output code to call MAMEs debugger\n");
5720: return 1;
5721: }
5722: printf("Z80 x86 asm emitter V0.6 for MAME\n");
5723: printf("Copyright (c) 1999 by Juergen Buchmueller ([email protected])\n");
5724:
5725: for (i = 1; av[i][0] == '-'; i++) {
5726: if (!strcmp(av[i], "-gas")) {
5727: as = GAS;
5728: } else if (!strcmp(av[i], "-nasm") || !strcmp(av[i], "-nasmw")) {
5729: as = NASM;
5730: } else if (!strcmp(av[i], "-tasm")) {
5731: as = TASM;
5732: } else if (!strcmp(av[i],"-verbose")) {
5733: if (++i < ac - 1) {
5734: sscanf(av[i], "%d", &verbose);
5735: }
5736: } else if (!strncmp(av[i], "-D", 2)) {
5737: if (!strcmp(&av[i][2],"MAME_DEBUG")) {
5738: mame_debug = 1;
5739: } else {
5740: /* fprintf(stderr, "ignored define '%s'\n", &av[i][2]); */
5741: }
5742: } else if (!strncmp(av[i], "-m", 2)) {
5743: if (!strncmp(&av[i][2],"386",3)) {
5744: align_funcs = 1;
5745: align_jumps = 1;
5746: align_loops = 1;
5747: } else
5748: if (!strncmp(&av[i][2],"486",3)) {
5749: align_funcs = 2;
5750: align_jumps = 2;
5751: align_loops = 1;
5752: } else
5753: if (!strncmp(&av[i][2],"pentium",3)) {
5754: align_funcs = 2;
5755: align_jumps = 2;
5756: align_loops = 1;
5757: } else
5758: if (!strncmp(&av[i][2],"align-functions=",16)) {
5759: sscanf(&av[i][18], "%d", &align_funcs);
5760: } else
5761: if (!strncmp(&av[i][2],"align-jumps=",12)) {
5762: sscanf(&av[i][14], "%d", &align_jumps);
5763: } else
5764: if (!strncmp(&av[i][2],"align-loops=",12)) {
5765: sscanf(&av[i][14], "%d", &align_loops);
5766: } else {
5767: /* fprintf(stderr, "ignored optimizing option '%s'\n", &av[i][2]); */
5768: }
5769: } else {
5770: /*
5771: * fprintf(stderr, "unsupported option '%s'\n", av[i]);
5772: * return 1;
5773: */
5774: }
5775: }
5776: if (as == GAS) printf("- GNU assembler output\n");
5777: if (as == NASM) printf("- NASM output\n");
5778: if (as == TASM) printf("- TASM output\n");
5779: if (mame_debug) printf("- with MAME_Debug code\n");
5780: printf("- verbose level %d\n", verbose);
5781: printf("- align functions %d (%d bytes)\n", align_funcs, 2<<align_funcs);
5782: printf("- align jumps %d (%d bytes)\n", align_jumps, 2<<align_jumps);
5783: printf("- align loops %d (%d bytes)\n", align_loops, 2<<align_loops);
5784:
5785: output = fopen(av[i], "w");
5786:
5787: mk_header();
5788: mk_interface();
5789: mk_memory_handlers();
5790: mk_opcodes(0x0000);
5791: mk_opcodes_ed();
5792: mk_opcodes_cb();
5793: mk_opcodes(0xdd00);
5794: mk_opcodes(0xfd00);
5795: mk_opcodes_xx();
5796:
5797: if (as == TASM)
5798: emit("\tend");
5799:
5800: printf("generated %d opcodes\n", opcodes);
5801: printf("functions rbyte:%d wbyte:%d rword:%d wword:%d\n",
5802: rbyte, wbyte, rword, wword);
5803:
5804: fclose(output);
5805: return 0;
5806: }
5807:
5808:
5809:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.