|
|
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.