|
|
1.1 ! root 1: #include "hd64180acc.h" ! 2: ! 3: #define ACC (*(hd64180acc*)®.f) ! 4: ! 5: // LDIR, INDR 等のリピート系命令の雛形。 ! 6: // いずれも OP(name) を実行して BC == 0 になるまでこの PC を繰り返すもの。 ! 7: // ジャンプする際には 2クロック追加で消費する。 ! 8: // フラグも OP(name) が変更した以上にはここでは変更しない。 ! 9: #define REPEAT_UNTIL(name) do { \ ! 10: OP_FUNC(name); \ ! 11: if (reg.GetBC() != 0) { \ ! 12: reg.pc -= 2; \ ! 13: CYCLE(2); \ ! 14: } \ ! 15: } while (0) ! 16: ! 17: uint32 ! 18: MPU64180Device::Read16(uint32 addr) ! 19: { ! 20: uint32 data; ! 21: ! 22: data = Read8(addr); ! 23: data |= Read8(addr + 1) << 8; ! 24: ! 25: return data; ! 26: } ! 27: ! 28: void ! 29: MPU64180Device::Write16(uint32 addr, uint32 data) ! 30: { ! 31: Write8(addr, data & 0xff); ! 32: Write8(addr + 1, data >> 8); ! 33: } ! 34: ! 35: uint32 ! 36: MPU64180Device::Fetch16() ! 37: { ! 38: uint32 data; ! 39: ! 40: data = Fetch8(); ! 41: data |= Fetch8() << 8; ! 42: ! 43: return data; ! 44: } ! 45: ! 46: void ! 47: MPU64180Device::Push16(uint32 data) ! 48: { ! 49: reg.sp -= 2; ! 50: Write16(reg.sp, data); ! 51: } ! 52: ! 53: uint32 ! 54: MPU64180Device::Pop16() ! 55: { ! 56: uint16 data = Read16(reg.sp); ! 57: reg.sp += 2; ! 58: return data; ! 59: } ! 60: ! 61: // HL (もしくは IX/IY) の値を取得する。 ! 62: uint32 ! 63: MPU64180Device::GetIHL() const ! 64: { ! 65: switch (ixiy) { ! 66: case USE_HL: return reg.GetHL(); break; ! 67: case USE_IX: return reg.ix; break; ! 68: case USE_IY: return reg.iy; break; ! 69: default: ! 70: PANIC("invalid ixiy = %d", (int)ixiy); ! 71: } ! 72: } ! 73: ! 74: // HL (もしくは IX/IY) に値を代入する。 ! 75: void ! 76: MPU64180Device::SetIHL(uint32 data) ! 77: { ! 78: switch (ixiy) { ! 79: case USE_HL: reg.SetHL(data); break; ! 80: case USE_IX: reg.ix = data; break; ! 81: case USE_IY: reg.iy = data; break; ! 82: default: ! 83: PANIC("invalid ixiy = %d", (int)ixiy); ! 84: } ! 85: } ! 86: ! 87: // (HL) 用に HL のアドレスを取得する。 ! 88: // IX/IY の時は (IX/IY + d) のアドレスを取得する。 ! 89: uint32 ! 90: MPU64180Device::LeaIHL() ! 91: { ! 92: uint32 addr = GetIHL(); ! 93: if (ixiy != USE_HL) { ! 94: // DD と DD CB で +d をフェッチする順序が違う。 ! 95: if ((int32)ixd < 0) { ! 96: ixd = Fetch8(); ! 97: } ! 98: addr += (int32)(int8)ixd; ! 99: } ! 100: return addr; ! 101: } ! 102: ! 103: // ww (BC, DE, HL, SP) の値を取得する。 ! 104: // ixiy なら HL の代わりに IX/IY の値を取得する。 ! 105: uint32 ! 106: MPU64180Device::GetWW(uint ww) const ! 107: { ! 108: switch (ww) { ! 109: case 0: return reg.GetBC(); ! 110: case 1: return reg.GetDE(); ! 111: case 2: return GetIHL(); ! 112: case 3: return reg.sp; ! 113: default: ! 114: PANIC("invalid ww = %u", ww); ! 115: } ! 116: } ! 117: ! 118: // ww (BC, DE, HL, SP) に値を代入する。 ! 119: // ixiy なら HL の代わりに IX/IY に値を取得する。 ! 120: void ! 121: MPU64180Device::SetWW(uint ww, uint32 data) ! 122: { ! 123: switch (ww) { ! 124: case 0: reg.SetBC(data); break; ! 125: case 1: reg.SetDE(data); break; ! 126: case 2: SetIHL(data); break; ! 127: case 3: reg.sp = data; break; ! 128: default: ! 129: PANIC("invalid ww = %u", ww); ! 130: } ! 131: } ! 132: ! 133: ! 134: // ここから命令 ! 135: ! 136: // 00000000: NOP ! 137: OP_DEF(nop) ! 138: { ! 139: CYCLE(3); ! 140: } ! 141: ! 142: // 00ww0001: LD ww,nn ! 143: // DD:00100001: LD IX,nn ! 144: OP_DEF(ld_ww_nn) ! 145: { ! 146: uint32 nn = Fetch16(); ! 147: uint ww = (op >> 4) & 3; ! 148: SetWW(ww, nn); ! 149: CYCLE_IX(9, 12); ! 150: } ! 151: ! 152: // 00ww0010: LD (ww),A ! 153: OP_DEF(ld_wwin_a) ! 154: { ! 155: uint ww = op >> 4; ! 156: uint32 addr = GetWW(ww); // ww は BC, DE のみ ! 157: Write8(addr, reg.a); ! 158: CYCLE_IX(7, 15); ! 159: } ! 160: ! 161: // 00ww0011: INC ww ! 162: // DD:00100011: INC IX ! 163: OP_DEF(inc_ww) ! 164: { ! 165: uint ww = op >> 4; ! 166: uint32 data = GetWW(ww); ! 167: data++; ! 168: SetWW(ww, data); ! 169: CYCLE_IX(4, 7); ! 170: } ! 171: ! 172: // 00rrr100: INC r ! 173: OP_DEF(inc_r) ! 174: { ! 175: uint r = op >> 3; ! 176: reg.r[r] = ACC.inc_8(reg.r[r]); ! 177: CYCLE(4); ! 178: } ! 179: ! 180: // 00rrr101: DEC r ! 181: OP_DEF(dec_r) ! 182: { ! 183: uint r = op >> 3; ! 184: reg.r[r] = ACC.dec_8(reg.r[r]); ! 185: CYCLE(4); ! 186: } ! 187: ! 188: // 00rrr110: LD r,n ! 189: OP_DEF(ld_r_n) ! 190: { ! 191: uint r = op >> 3; ! 192: reg.r[r] = Fetch8(); ! 193: CYCLE(6); ! 194: } ! 195: ! 196: // 00000111: RLCA ! 197: OP_DEF(rlca) ! 198: { ! 199: reg.a = ACC.rlc_8(reg.a); ! 200: CYCLE(3); ! 201: } ! 202: ! 203: // 00001000: EX AF,AF' ! 204: OP_DEF(ex_af_af) ! 205: { ! 206: uint8 tmpa = reg.a; ! 207: uint8 tmpf = reg.f.Get(); ! 208: reg.a = reg.ex.a; ! 209: reg.f.Set(reg.ex.f.Get()); ! 210: reg.ex.a = tmpa; ! 211: reg.ex.f.Set(tmpf); ! 212: CYCLE(4); ! 213: } ! 214: ! 215: // 00ww1001: ADD HL,ww ! 216: // DD:00ww1001: ADD IX,ww ! 217: OP_DEF(add_hl_ww) ! 218: { ! 219: uint ww = op >> 4; ! 220: uint32 src = GetWW(ww); ! 221: uint32 dst = GetIHL(); ! 222: dst = ACC.add_16(dst, src); ! 223: SetIHL(dst); ! 224: CYCLE_IX(7, 10); ! 225: } ! 226: ! 227: // 00ww1010: LD A,(ww) ! 228: OP_DEF(ld_a_wwin) ! 229: { ! 230: uint ww = op >> 4; ! 231: uint32 addr = GetWW(ww); // ww は BC, DE のみ ! 232: reg.a = Read8(addr); ! 233: CYCLE(6); ! 234: } ! 235: ! 236: // 00ww1011: DEC ww ! 237: // DD:00101011: DEC IX ! 238: OP_DEF(dec_ww) ! 239: { ! 240: uint ww = op >> 4; ! 241: uint32 data = GetWW(ww); ! 242: data--; ! 243: SetWW(ww, data); ! 244: CYCLE_IX(4, 7); ! 245: } ! 246: ! 247: // 00001111: RRCA ! 248: OP_DEF(rrca) ! 249: { ! 250: reg.a = ACC.rrc_8(reg.a); ! 251: CYCLE(3); ! 252: } ! 253: ! 254: // 00010000: DJNZ n ! 255: OP_DEF(djnz) ! 256: { ! 257: int8 n = Fetch8(); ! 258: reg.b--; ! 259: if (reg.b != 0) { ! 260: Jump(reg.pc + n); ! 261: CYCLE(9); ! 262: } else { ! 263: CYCLE(7); ! 264: } ! 265: } ! 266: ! 267: // 00010111: RLA ! 268: OP_DEF(rla) ! 269: { ! 270: reg.a = ACC.rl_8(reg.a); ! 271: CYCLE(3); ! 272: } ! 273: ! 274: // 00011000: JR n ! 275: OP_DEF(jr) ! 276: { ! 277: int8 n = Fetch8(); ! 278: Jump(reg.pc + n); ! 279: CYCLE(8); ! 280: } ! 281: ! 282: // 00011111: RRA ! 283: OP_DEF(rra) ! 284: { ! 285: reg.a = ACC.rr_8(reg.a); ! 286: CYCLE(3); ! 287: } ! 288: ! 289: // 00100000: JR NZ,n ! 290: OP_DEF(jr_nz) ! 291: { ! 292: int8 n = Fetch8(); ! 293: if (reg.f.IsZ() == false) { ! 294: Jump(reg.pc + n); ! 295: CYCLE(8); ! 296: } else { ! 297: CYCLE(6); ! 298: } ! 299: } ! 300: ! 301: // 00100010: LD (nn),HL ! 302: // DD:00100010: LD (nn),IX ! 303: OP_DEF(ld_nnin_hl) ! 304: { ! 305: uint32 nn = Fetch16(); ! 306: Write16(nn, GetIHL()); ! 307: CYCLE_IX(16, 19); ! 308: } ! 309: ! 310: // 00100111: DAA ! 311: OP_DEF(daa) ! 312: { ! 313: // XXX 未実装 ! 314: putlog(0, "DAA (NOT IMPLEMENTED)"); ! 315: CYCLE(4); ! 316: } ! 317: ! 318: // 00101000: JR Z,n ! 319: OP_DEF(jr_z) ! 320: { ! 321: int8 n = Fetch8(); ! 322: if (reg.f.IsZ()) { ! 323: Jump(reg.pc + n); ! 324: CYCLE(8); ! 325: } else { ! 326: CYCLE(6); ! 327: } ! 328: } ! 329: ! 330: // 00101010: LD HL,(nn) ! 331: // DD:00101010: LD IX,(nn) ! 332: OP_DEF(ld_hl_nnin) ! 333: { ! 334: uint32 nn = Fetch16(); ! 335: uint32 src = Read16(nn); ! 336: SetIHL(src); ! 337: CYCLE_IX(15, 18); ! 338: } ! 339: ! 340: // 00101111: CPL ! 341: OP_DEF(cpl) ! 342: { ! 343: reg.a = ~reg.a; ! 344: reg.f.SetH(true); ! 345: reg.f.SetN(true); ! 346: CYCLE(3); ! 347: } ! 348: ! 349: // 00110000: JR NC,n ! 350: OP_DEF(jr_nc) ! 351: { ! 352: int8 n = Fetch8(); ! 353: if (reg.f.IsC() == false) { ! 354: Jump(reg.pc + n); ! 355: CYCLE(8); ! 356: } else { ! 357: CYCLE(6); ! 358: } ! 359: } ! 360: ! 361: // 00110010: LD (nn),A ! 362: OP_DEF(ld_nnin_a) ! 363: { ! 364: uint32 addr = Fetch16(); ! 365: Write8(addr, reg.a); ! 366: CYCLE(13); ! 367: } ! 368: ! 369: // 00110100: INC (HL) ! 370: // DD:00110100: INC (IX+d) ! 371: OP_DEF(inc_hlin) ! 372: { ! 373: uint32 addr = LeaIHL(); ! 374: uint32 src = Read8(addr); ! 375: uint32 dst = ACC.inc_8(src); ! 376: Write8(addr, dst); ! 377: CYCLE_IX(10, 18); ! 378: } ! 379: ! 380: // 00110101: DEC (HL) ! 381: // DD:00110101: DEC (IX+d) ! 382: OP_DEF(dec_hlin) ! 383: { ! 384: uint32 addr = LeaIHL(); ! 385: uint32 src = Read8(addr); ! 386: uint32 dst = ACC.dec_8(src); ! 387: Write8(addr, dst); ! 388: CYCLE_IX(10, 18); ! 389: } ! 390: ! 391: // 00110110: LD (HL),n ! 392: // DD:00110110: LD (IX+d),n ! 393: OP_DEF(ld_hlin_n) ! 394: { ! 395: uint32 addr = LeaIHL(); ! 396: uint32 src = Fetch8(); ! 397: Write8(addr, src); ! 398: CYCLE_IX(9, 15); ! 399: } ! 400: ! 401: // 00110111: SCF ! 402: OP_DEF(scf) ! 403: { ! 404: reg.f.SetC(true); ! 405: reg.f.SetH(false); ! 406: reg.f.SetN(false); ! 407: CYCLE(3); ! 408: } ! 409: ! 410: // 00111000: JR C,n ! 411: OP_DEF(jr_c) ! 412: { ! 413: int8 n = Fetch8(); ! 414: if (reg.f.IsC()) { ! 415: Jump(reg.pc + n); ! 416: CYCLE(8); ! 417: } else { ! 418: CYCLE(6); ! 419: } ! 420: } ! 421: ! 422: // 00111010: LD A,(nn) ! 423: OP_DEF(ld_a_nnin) ! 424: { ! 425: uint32 nn = Fetch16(); ! 426: reg.a = Read8(nn); ! 427: CYCLE(12); ! 428: } ! 429: ! 430: // 00111111: CCF ! 431: OP_DEF(ccf) ! 432: { ! 433: reg.f.SetC(!reg.f.IsC()); ! 434: reg.f.SetH(false); ! 435: reg.f.SetN(false); ! 436: CYCLE(3); ! 437: } ! 438: ! 439: // 01rrrsss: LD r,s ! 440: OP_DEF(ld_r_s) ! 441: { ! 442: uint d = (op >> 3) & 7; ! 443: uint s = op & 7; ! 444: reg.r[d] = reg.r[s]; ! 445: CYCLE(4); ! 446: } ! 447: ! 448: // 01rrr110: LD r,(HL) ! 449: // DD:01rrr110: LD r,(IX+d) ! 450: OP_DEF(ld_r_hlin) ! 451: { ! 452: uint d = (op >> 3) & 7; ! 453: uint16 addr = LeaIHL(); ! 454: reg.r[d] = Read8(addr); ! 455: CYCLE_IX(6, 14); ! 456: } ! 457: ! 458: // 01110sss: LD (HL),s ! 459: // DD:01110sss: LD (IX+d),s ! 460: OP_DEF(ld_hlin_s) ! 461: { ! 462: uint s = op & 7; ! 463: uint32 addr = LeaIHL(); ! 464: Write8(addr, reg.r[s]); ! 465: CYCLE_IX(7, 15); ! 466: } ! 467: ! 468: // 01110110: HALT ! 469: OP_DEF(halt) ! 470: { ! 471: opmode = OpMode::Halt; ! 472: putlog(1, "Halt"); ! 473: CYCLE(3); ! 474: } ! 475: ! 476: // 10000rrr: ADD A,r ! 477: OP_DEF(add_a_r) ! 478: { ! 479: uint r = op & 7; ! 480: reg.a = ACC.add_8(reg.a, reg.r[r]); ! 481: CYCLE(4); ! 482: } ! 483: ! 484: // 10000110: ADD A,(HL) ! 485: // DD:10000110: ADD A,(IX+d) ! 486: OP_DEF(add_a_hlin) ! 487: { ! 488: uint32 addr = LeaIHL(); ! 489: uint32 src = Read8(addr); ! 490: reg.a = ACC.add_8(reg.a, src); ! 491: CYCLE_IX(6, 14); ! 492: } ! 493: ! 494: // 10001rrr: ADC A,r ! 495: OP_DEF(adc_a_r) ! 496: { ! 497: uint r = op & 7; ! 498: reg.a = ACC.adc_8(reg.a, reg.r[r]); ! 499: CYCLE(4); ! 500: } ! 501: ! 502: // 10001110: ADC A,(HL) ! 503: // DD:10001110: ADC A,(IX+d) ! 504: OP_DEF(adc_a_hlin) ! 505: { ! 506: uint32 addr = LeaIHL(); ! 507: uint32 src = Read8(addr); ! 508: reg.a = ACC.adc_8(reg.a, src); ! 509: CYCLE_IX(6, 14); ! 510: } ! 511: ! 512: // 10010rrr: SUB r ! 513: OP_DEF(sub_r) ! 514: { ! 515: uint r = op & 7; ! 516: reg.a = ACC.sub_8(reg.a, reg.r[r]); ! 517: CYCLE(4); ! 518: } ! 519: ! 520: // 10010110: SUB (HL) ! 521: // DD:10010110: SUB (IX+d) ! 522: OP_DEF(sub_hlin) ! 523: { ! 524: uint32 addr = LeaIHL(); ! 525: uint32 src = Read8(addr); ! 526: reg.a = ACC.sub_8(reg.a, src); ! 527: CYCLE_IX(6, 14); ! 528: } ! 529: ! 530: // 10011rrr: SBC A,r ! 531: OP_DEF(sbc_a_r) ! 532: { ! 533: uint r = op & 7; ! 534: reg.a = ACC.sbc_8(reg.a, reg.r[r]); ! 535: CYCLE(4); ! 536: } ! 537: ! 538: // 10011110: SBC A,(HL) ! 539: // DD:10011110: SBC A,(IX+d) ! 540: OP_DEF(sbc_a_hlin) ! 541: { ! 542: uint32 addr = LeaIHL(); ! 543: uint32 src = Read8(addr); ! 544: reg.a = ACC.sbc_8(reg.a, src); ! 545: CYCLE_IX(6, 14); ! 546: } ! 547: ! 548: // 10100rrr: AND r ! 549: OP_DEF(and_r) ! 550: { ! 551: uint r = op & 7; ! 552: reg.a = ACC.and_8(reg.a, reg.r[r]); ! 553: CYCLE(4); ! 554: } ! 555: ! 556: // 10100110: AND (HL) ! 557: // DD:10100110: AND (IX+d) ! 558: OP_DEF(and_hlin) ! 559: { ! 560: uint16 addr = LeaIHL(); ! 561: uint32 src = Read8(addr); ! 562: reg.a = ACC.and_8(reg.a, src); ! 563: CYCLE_IX(6, 14); ! 564: } ! 565: ! 566: // 10101rrr: XOR r ! 567: OP_DEF(xor_r) ! 568: { ! 569: uint r = op & 7; ! 570: reg.a = ACC.xor_8(reg.a, reg.r[r]); ! 571: CYCLE(4); ! 572: } ! 573: ! 574: // 10101110: XOR (HL) ! 575: // DD:10101110: XOR (IX+d) ! 576: OP_DEF(xor_hlin) ! 577: { ! 578: uint16 addr = LeaIHL(); ! 579: uint32 src = Read8(addr); ! 580: reg.a = ACC.xor_8(reg.a, src); ! 581: CYCLE_IX(6, 14); ! 582: } ! 583: ! 584: // 10110rrr: OR r ! 585: OP_DEF(or_r) ! 586: { ! 587: uint r = op & 7; ! 588: reg.a = ACC.or_8(reg.a, reg.r[r]); ! 589: CYCLE(4); ! 590: } ! 591: ! 592: // 10110110: OR (HL) ! 593: // DD:10110110: OR (IX+d) ! 594: OP_DEF(or_hlin) ! 595: { ! 596: uint16 addr = LeaIHL(); ! 597: uint32 src = Read8(addr); ! 598: reg.a = ACC.or_8(reg.a, src); ! 599: CYCLE_IX(6, 14); ! 600: } ! 601: ! 602: // 10111rrr: CP r ! 603: OP_DEF(cp_r) ! 604: { ! 605: uint r = op & 7; ! 606: ACC.sub_8(reg.a, reg.r[r]); ! 607: CYCLE(4); ! 608: } ! 609: ! 610: // 10111110: CP (HL) ! 611: // DD:10111110: CP (IX+d) ! 612: OP_DEF(cp_hlin) ! 613: { ! 614: uint16 addr = LeaIHL(); ! 615: uint32 src = Read8(addr); ! 616: ACC.sub_8(reg.a, src); ! 617: CYCLE_IX(6, 14); ! 618: } ! 619: ! 620: void ! 621: MPU64180Device::ops_ret() ! 622: { ! 623: uint16 addr = Pop16(); ! 624: Jump(addr); ! 625: } ! 626: ! 627: // 11fff000: RET f ! 628: OP_DEF(ret_f) ! 629: { ! 630: uint fff = (op >> 3) & 7; ! 631: if (reg.f.IsCond(fff)) { ! 632: ops_ret(); ! 633: CYCLE(10); ! 634: } else { ! 635: CYCLE(5); ! 636: } ! 637: } ! 638: ! 639: // 11zz0001: POP zz ! 640: // DD:11100001: POP IX ! 641: OP_DEF(pop_zz) ! 642: { ! 643: // ここでは zz のうち BC, DE, HL のみなので ww が使える ! 644: uint zz = (op >> 4) & 3; ! 645: uint16 data = Pop16(); ! 646: SetWW(zz, data); ! 647: CYCLE_IX(9, 12); ! 648: } ! 649: ! 650: // 11fff010: JP f,nn ! 651: OP_DEF(jp_f_nn) ! 652: { ! 653: uint fff = (op >> 3) & 7; ! 654: uint16 addr = Fetch16(); ! 655: if (reg.f.IsCond(fff)) { ! 656: Jump(addr); ! 657: CYCLE(9); ! 658: } else { ! 659: CYCLE(6); ! 660: } ! 661: } ! 662: ! 663: // 11000011: JP nn ! 664: OP_DEF(jp_nn) ! 665: { ! 666: uint32 addr = Fetch16(); ! 667: Jump(addr); ! 668: CYCLE(9); ! 669: } ! 670: ! 671: // 11fff100: CALL f,nn ! 672: OP_DEF(call_f_nn) ! 673: { ! 674: uint fff = (op >> 3) & 7; ! 675: uint16 nn = Fetch16(); ! 676: if (reg.f.IsCond(fff)) { ! 677: Push16(reg.pc); ! 678: Jump(nn); ! 679: CYCLE(16); ! 680: } else { ! 681: CYCLE(6); ! 682: } ! 683: } ! 684: ! 685: // 11zz0101: PUSH zz ! 686: // DD:11100101: PUSH IX ! 687: OP_DEF(push_zz) ! 688: { ! 689: // ここでは zz のうち BC, DE, HL のみなので ww が使える ! 690: uint zz = (op >> 4) & 3; ! 691: uint16 data = GetWW(zz); ! 692: Push16(data); ! 693: CYCLE_IX(11, 14); ! 694: } ! 695: ! 696: // 11000110: ADD A,n ! 697: OP_DEF(add_a_n) ! 698: { ! 699: uint32 n = Fetch8(); ! 700: reg.a = ACC.add_8(reg.a, n); ! 701: CYCLE(6); ! 702: } ! 703: ! 704: // 11vvv111: RST v ! 705: OP_DEF(rst) ! 706: { ! 707: Push16(reg.pc); ! 708: uint v = op & 0x38; ! 709: Jump(v); ! 710: CYCLE(11); ! 711: } ! 712: ! 713: // 11001001: RET ! 714: OP_DEF(ret) ! 715: { ! 716: ops_ret(); ! 717: CYCLE(9); ! 718: } ! 719: ! 720: // 11001011: op_CB ! 721: OP_DEF(cb) ! 722: { ! 723: // 2バイト目をフェッチ ! 724: op = Fetch8(); ! 725: // で分岐 ! 726: switch (op) { ! 727: #include "hd64180switch_cb.inc" ! 728: default: ! 729: op_illegal(2); ! 730: break; ! 731: } ! 732: } ! 733: ! 734: // 11001101: CALL nn ! 735: OP_DEF(call) ! 736: { ! 737: uint16 nn = Fetch16(); ! 738: Push16(reg.pc); ! 739: Jump(nn); ! 740: CYCLE(16); ! 741: } ! 742: ! 743: // 11001110: ADC A,n ! 744: OP_DEF(adc_a_n) ! 745: { ! 746: uint32 n = Fetch8(); ! 747: reg.a = ACC.adc_8(reg.a, n); ! 748: CYCLE(6); ! 749: } ! 750: ! 751: // 11010011: OUT (n),A ! 752: OP_DEF(out_n_a) ! 753: { ! 754: uint32 n = Fetch8(); ! 755: // バスの上位には A が出る ! 756: uint32 addr = (reg.a << 8) | n; ! 757: WriteIO(addr, reg.a); ! 758: CYCLE(10); ! 759: } ! 760: ! 761: // 11010110: SUB n ! 762: OP_DEF(sub_n) ! 763: { ! 764: uint32 n = Fetch8(); ! 765: reg.a = ACC.sub_8(reg.a, n); ! 766: CYCLE(6); ! 767: } ! 768: ! 769: // 11011001: EXX ! 770: OP_DEF(exx) ! 771: { ! 772: uint8 tmpb = reg.b; ! 773: uint8 tmpc = reg.c; ! 774: uint8 tmpd = reg.d; ! 775: uint8 tmpe = reg.e; ! 776: uint8 tmph = reg.h; ! 777: uint8 tmpl = reg.l; ! 778: reg.b = reg.ex.b; ! 779: reg.c = reg.ex.c; ! 780: reg.d = reg.ex.d; ! 781: reg.e = reg.ex.e; ! 782: reg.h = reg.ex.h; ! 783: reg.l = reg.ex.l; ! 784: reg.ex.b = tmpb; ! 785: reg.ex.c = tmpc; ! 786: reg.ex.d = tmpd; ! 787: reg.ex.e = tmpe; ! 788: reg.ex.h = tmph; ! 789: reg.ex.l = tmpl; ! 790: CYCLE(3); ! 791: } ! 792: ! 793: // 11011011: IN A,(n) ! 794: OP_DEF(in_a_n) ! 795: { ! 796: uint32 n = Fetch8(); ! 797: // バスの上位には A が出る ! 798: uint32 addr = (reg.a << 8) | n; ! 799: reg.a = ReadIO(addr); ! 800: CYCLE(9); ! 801: } ! 802: ! 803: // DD/FD の共通部 ! 804: void ! 805: MPU64180Device::ops_ddfd(ixiy_t xy) ! 806: { ! 807: ixiy = xy; ! 808: ! 809: // 2バイト目をフェッチ ! 810: op = Fetch8(); ! 811: // で分岐 ! 812: switch (op) { ! 813: #include "hd64180switch_dd.inc" ! 814: default: ! 815: op_illegal(2); ! 816: break; ! 817: } ! 818: } ! 819: ! 820: // 11011101: op_DD ! 821: OP_DEF(dd) ! 822: { ! 823: ops_ddfd(USE_IX); ! 824: } ! 825: ! 826: // 11011110: SBC A,n ! 827: OP_DEF(sbc_a_n) ! 828: { ! 829: uint32 n = Fetch8(); ! 830: reg.a = ACC.sbc_8(reg.a, n); ! 831: CYCLE(6); ! 832: } ! 833: ! 834: // 11100011: EX (SP),HL ! 835: // DD:11100011: EX (SP),IX ! 836: OP_DEF(ex_sp_hl) ! 837: { ! 838: uint32 tmp = Read16(reg.sp); ! 839: Write16(reg.sp, GetIHL()); ! 840: SetIHL(tmp); ! 841: CYCLE_IX(16, 19); ! 842: } ! 843: ! 844: // 11100110: AND n ! 845: OP_DEF(and_n) ! 846: { ! 847: uint32 src = Fetch8(); ! 848: reg.a = ACC.and_8(reg.a, src); ! 849: CYCLE(6); ! 850: } ! 851: ! 852: // 11101001: JP (HL) ! 853: // DD:11101001: JP (IX) ! 854: OP_DEF(jp_hl) ! 855: { ! 856: Jump(GetIHL()); ! 857: CYCLE_IX(3, 6); ! 858: } ! 859: ! 860: // 11101011: EX DE,HL ! 861: OP_DEF(ex_de_hl) ! 862: { ! 863: uint16 tmp = reg.GetDE(); ! 864: reg.SetDE(reg.GetHL()); ! 865: reg.SetHL(tmp); ! 866: CYCLE(3); ! 867: } ! 868: ! 869: // 11101101: op_ED ! 870: OP_DEF(ed) ! 871: { ! 872: op = Fetch8(); ! 873: ! 874: switch (op) { ! 875: #include "hd64180switch_ed.inc" ! 876: default: ! 877: op_illegal(2); ! 878: break; ! 879: } ! 880: } ! 881: ! 882: // 11101110: XOR n ! 883: OP_DEF(xor_n) ! 884: { ! 885: uint32 src = Fetch8(); ! 886: reg.a = ACC.xor_8(reg.a, src); ! 887: CYCLE(6); ! 888: } ! 889: ! 890: // 11110001: POP AF ! 891: OP_DEF(pop_af) ! 892: { ! 893: uint16 data = Pop16(); ! 894: reg.a = data >> 8; ! 895: reg.f.Set(data & 0xff); ! 896: CYCLE(9); ! 897: } ! 898: ! 899: // 11110011: DI ! 900: OP_DEF(di) ! 901: { ! 902: ief1 = false; ! 903: ief2 = false; ! 904: ! 905: // DI 命令の直後は割り込みをサンプルしない。HD647180.pdf, p.205 ! 906: intcheck = false; ! 907: ! 908: CYCLE(3); ! 909: } ! 910: ! 911: // 11110101: PUSH AF ! 912: OP_DEF(push_af) ! 913: { ! 914: uint16 data; ! 915: data = reg.a << 8; ! 916: data |= reg.f.Get(); ! 917: Push16(data); ! 918: CYCLE(11); ! 919: } ! 920: ! 921: // 11110110: OR n ! 922: OP_DEF(or_n) ! 923: { ! 924: uint32 src = Fetch8(); ! 925: reg.a = ACC.or_8(reg.a, src); ! 926: CYCLE(6); ! 927: } ! 928: ! 929: // 11111001: LD SP,HL ! 930: // DD:11111001: LD SP,IX ! 931: OP_DEF(ld_sp_hl) ! 932: { ! 933: reg.sp = GetIHL(); ! 934: CYCLE_IX(4, 7); ! 935: } ! 936: ! 937: // 11111011: EI ! 938: OP_DEF(ei) ! 939: { ! 940: ief1 = true; ! 941: ief2 = true; ! 942: ! 943: // EI 命令の直後は割り込みをサンプルしない。HD647180.pdf, p.205 ! 944: intcheck = false; ! 945: ! 946: CYCLE(3); ! 947: } ! 948: ! 949: // 11111101: op_FD ! 950: OP_DEF(fd) ! 951: { ! 952: ops_ddfd(USE_IY); ! 953: } ! 954: ! 955: // 11111110: CP n ! 956: OP_DEF(cp_n) ! 957: { ! 958: uint32 n = Fetch8(); ! 959: ACC.sub_8(reg.a, n); ! 960: CYCLE(6); ! 961: } ! 962: ! 963: // CB:00000rrr: RLC r ! 964: OP_DEF(rlc_r) ! 965: { ! 966: uint r = op & 7; ! 967: reg.r[r] = ACC.in_8(ACC.rlc_8(reg.r[r])); ! 968: CYCLE(7); ! 969: } ! 970: ! 971: // CB:00000110: RLC (HL) ! 972: // DD_CB:00000110: RLC (IX+d) ! 973: OP_DEF(rlc_hlin) ! 974: { ! 975: uint32 addr = LeaIHL(); ! 976: uint32 src = Read8(addr); ! 977: uint32 res = ACC.in_8(ACC.rlc_8(src)); ! 978: Write8(addr, res); ! 979: CYCLE_IX(13, 19); ! 980: } ! 981: ! 982: // CB:00001rrr: RRC r ! 983: OP_DEF(rrc_r) ! 984: { ! 985: uint r = op & 7; ! 986: reg.r[r] = ACC.in_8(ACC.rrc_8(reg.r[r])); ! 987: CYCLE(7); ! 988: } ! 989: ! 990: // CB:00001110: RRC (HL) ! 991: // DD_CB:00001110: RRC (IX+d) ! 992: OP_DEF(rrc_hlin) ! 993: { ! 994: uint32 addr = LeaIHL(); ! 995: uint32 src = Read8(addr); ! 996: uint32 res = ACC.in_8(ACC.rrc_8(src)); ! 997: Write8(addr, res); ! 998: CYCLE_IX(13, 19); ! 999: } ! 1000: ! 1001: // CB:00010rrr: RL r ! 1002: OP_DEF(rl_r) ! 1003: { ! 1004: uint r = op & 7; ! 1005: reg.r[r] = ACC.in_8(ACC.rl_8(reg.r[r])); ! 1006: CYCLE(7); ! 1007: } ! 1008: ! 1009: // CB:00010110: RL (HL) ! 1010: // DD_CB:00010110: RL (IX+d) ! 1011: OP_DEF(rl_hlin) ! 1012: { ! 1013: uint32 addr = LeaIHL(); ! 1014: uint32 src = Read8(addr); ! 1015: uint32 res = ACC.in_8(ACC.rl_8(src)); ! 1016: Write8(addr, res); ! 1017: CYCLE_IX(13, 19); ! 1018: } ! 1019: ! 1020: // CB:00011rrr: RR r ! 1021: OP_DEF(rr_r) ! 1022: { ! 1023: uint r = op & 7; ! 1024: reg.r[r] = ACC.in_8(ACC.rr_8(reg.r[r])); ! 1025: CYCLE(7); ! 1026: } ! 1027: ! 1028: // CB:00011110: RR (HL) ! 1029: // DD_CB:00011110: RR (IX+d) ! 1030: OP_DEF(rr_hlin) ! 1031: { ! 1032: uint32 addr = LeaIHL(); ! 1033: uint32 src = Read8(addr); ! 1034: uint32 res = ACC.in_8(ACC.rr_8(src)); ! 1035: Write8(addr, res); ! 1036: CYCLE_IX(13, 19); ! 1037: } ! 1038: ! 1039: // CB:00100rrr: SLA r ! 1040: OP_DEF(sla_r) ! 1041: { ! 1042: uint r = op & 7; ! 1043: reg.r[r] = ACC.in_8(ACC.sla_8(reg.r[r])); ! 1044: CYCLE(7); ! 1045: } ! 1046: ! 1047: // CB:00100110: SLA (HL) ! 1048: // DD_CB:00100110: SLA (IX+d) ! 1049: OP_DEF(sla_hlin) ! 1050: { ! 1051: uint32 addr = LeaIHL(); ! 1052: uint32 src = Read8(addr); ! 1053: uint32 res = ACC.in_8(ACC.sla_8(src)); ! 1054: Write8(addr, res); ! 1055: CYCLE_IX(13, 19); ! 1056: } ! 1057: ! 1058: // CB:00101rrr: SRA r ! 1059: OP_DEF(sra_r) ! 1060: { ! 1061: uint r = op & 7; ! 1062: reg.r[r] = ACC.in_8(ACC.sra_8(reg.r[r])); ! 1063: CYCLE(7); ! 1064: } ! 1065: ! 1066: // CB:00101110: SRA (HL) ! 1067: // DD_CB:00101110: SRA (IX+d) ! 1068: OP_DEF(sra_hlin) ! 1069: { ! 1070: uint32 addr = LeaIHL(); ! 1071: uint32 src = Read8(addr); ! 1072: uint32 res = ACC.in_8(ACC.sra_8(src)); ! 1073: Write8(addr, res); ! 1074: CYCLE_IX(13, 19); ! 1075: } ! 1076: ! 1077: // CB:00111rrr: SRL r ! 1078: OP_DEF(srl_r) ! 1079: { ! 1080: uint r = op & 7; ! 1081: reg.r[r] = ACC.in_8(ACC.srl_8(reg.r[r])); ! 1082: CYCLE(7); ! 1083: } ! 1084: ! 1085: // CB:00111110: SRL (HL) ! 1086: // DD_CB:00111110: SRL (IX+d) ! 1087: OP_DEF(srl_hlin) ! 1088: { ! 1089: uint32 addr = LeaIHL(); ! 1090: uint32 src = Read8(addr); ! 1091: uint32 res = ACC.in_8(ACC.srl_8(src)); ! 1092: Write8(addr, res); ! 1093: CYCLE_IX(13, 19); ! 1094: } ! 1095: ! 1096: // CB:01bbbrrr: BIT b,r ! 1097: OP_DEF(bit_r) ! 1098: { ! 1099: uint b = (op >> 3) & 7; ! 1100: uint r = op & 7; ! 1101: ACC.bit_8(b, reg.r[r]); ! 1102: CYCLE(6); ! 1103: } ! 1104: ! 1105: // CB:01bbb110: BIT b,(HL) ! 1106: // DD_CB:01bbb110: BIT b,(IX+d) ! 1107: OP_DEF(bit_hlin) ! 1108: { ! 1109: uint b = (op >> 3) & 7; ! 1110: uint32 addr = LeaIHL(); ! 1111: uint32 data = Read8(addr); ! 1112: ACC.bit_8(b, data); ! 1113: CYCLE_IX(9, 15); ! 1114: } ! 1115: ! 1116: // CB:10bbbrrr: RES b,r ! 1117: OP_DEF(res_r) ! 1118: { ! 1119: uint b = (op >> 3) & 7; ! 1120: uint r = op & 7; ! 1121: reg.r[r] &= ~(1U << b); ! 1122: CYCLE(7); ! 1123: } ! 1124: ! 1125: // CB:10bbb110: RES b,(HL) ! 1126: // DD_CB:10bbb110: RES b,(IX+d) ! 1127: OP_DEF(res_hlin) ! 1128: { ! 1129: uint b = (op >> 3) & 7; ! 1130: uint32 addr = LeaIHL(); ! 1131: uint32 data = Read8(addr); ! 1132: data &= ~(1U << b); ! 1133: Write8(addr, data); ! 1134: CYCLE_IX(13, 19); ! 1135: } ! 1136: ! 1137: // CB:11bbbrrr: SET b,r ! 1138: OP_DEF(set_r) ! 1139: { ! 1140: uint b = (op >> 3) & 7; ! 1141: uint r = op & 7; ! 1142: reg.r[r] |= 1U << b; ! 1143: CYCLE(7); ! 1144: } ! 1145: ! 1146: // CB:11bbb110: SET b,(HL) ! 1147: // DD_CB:11bbb110: SET b,(IX+d) ! 1148: OP_DEF(set_hlin) ! 1149: { ! 1150: uint b = (op >> 3) & 7; ! 1151: uint32 addr = LeaIHL(); ! 1152: uint32 data = Read8(addr); ! 1153: data |= 1U << b; ! 1154: Write8(addr, data); ! 1155: CYCLE_IX(13, 19); ! 1156: } ! 1157: ! 1158: // ED:00rrr000: IN0 r,(n) (HD64*180 only) ! 1159: OP_DEF(in0_r_n) ! 1160: { ! 1161: uint32 n = Fetch8(); ! 1162: uint32 src = ReadIO(n); ! 1163: uint r = op >> 3; ! 1164: reg.r[r] = ACC.in_8(src); ! 1165: CYCLE(12); ! 1166: } ! 1167: ! 1168: // ED:00rrr001: OUT0 (n),r (HD64*180 only) ! 1169: OP_DEF(out0_n_r) ! 1170: { ! 1171: uint32 n = Fetch8(); ! 1172: uint32 r = op >> 3; ! 1173: WriteIO(n, reg.r[r]); ! 1174: CYCLE(13); ! 1175: } ! 1176: ! 1177: // ED:00rrr100: TST r (HD64*180 only) ! 1178: OP_DEF(tst_r) ! 1179: { ! 1180: uint r = op & 7; ! 1181: ACC.tst_8(reg.a, reg.r[r]); ! 1182: CYCLE(7); ! 1183: } ! 1184: ! 1185: // ED:00110000: IN0 F,(n) (HD64*180 only) ! 1186: OP_DEF(in0_f_n) ! 1187: { ! 1188: uint32 n = Fetch8(); ! 1189: uint32 src = ReadIO(n); ! 1190: ACC.in_8(src); ! 1191: CYCLE(12); ! 1192: } ! 1193: ! 1194: // ED:00110100: TST (HL) (HD64*180 only) ! 1195: OP_DEF(tst_hlin) ! 1196: { ! 1197: uint16 addr = reg.GetHL(); ! 1198: uint32 src = Read8(addr); ! 1199: ACC.tst_8(reg.a, src); ! 1200: CYCLE(10); ! 1201: } ! 1202: ! 1203: // ED:01rrr000: IN r,(C) ! 1204: OP_DEF(in_r_c) ! 1205: { ! 1206: uint r = (op >> 3) & 7; ! 1207: // バスの上位には B が出る ! 1208: uint32 addr = reg.GetBC(); ! 1209: uint32 data = ReadIO(addr); ! 1210: reg.r[r] = ACC.in_8(data); ! 1211: CYCLE(9); ! 1212: } ! 1213: ! 1214: // ED:01rrr001: OUT (C),r ! 1215: OP_DEF(out_c_r) ! 1216: { ! 1217: uint r = (op >> 3) & 7; ! 1218: // バスの上位には B が出る ! 1219: uint32 addr = reg.GetBC(); ! 1220: WriteIO(addr, reg.r[r]); ! 1221: CYCLE(10); ! 1222: } ! 1223: ! 1224: // ED:01ww0010: SBC HL,ww ! 1225: OP_DEF(sbc_hl_ww) ! 1226: { ! 1227: uint ww = (op >> 4) & 3; ! 1228: uint32 src = GetWW(ww); ! 1229: uint32 dst = reg.GetHL(); ! 1230: dst = ACC.sbc_16(dst, src); ! 1231: reg.SetHL(dst); ! 1232: CYCLE(10); ! 1233: } ! 1234: ! 1235: // ED:01ww0011: LD (nn),ww ! 1236: OP_DEF(ld_nnin_ww) ! 1237: { ! 1238: uint ww = (op >> 4) & 3; ! 1239: uint32 src = GetWW(ww); ! 1240: uint32 nn = Fetch16(); ! 1241: Write16(nn, src); ! 1242: CYCLE(19); ! 1243: } ! 1244: ! 1245: // ED:01000100: NEG ! 1246: OP_DEF(neg) ! 1247: { ! 1248: reg.a = ACC.sub_8(0, reg.a); ! 1249: CYCLE(6); ! 1250: } ! 1251: ! 1252: // ED:01000101: RETN ! 1253: OP_DEF(retn) ! 1254: { ! 1255: ief1 = ief2; ! 1256: Jump(Pop16()); ! 1257: } ! 1258: ! 1259: // ED:01000110: IM 0 ! 1260: OP_DEF(im_0) ! 1261: { ! 1262: int0mode = 0; ! 1263: putlog(1, "IM %d", int0mode); ! 1264: CYCLE(6); ! 1265: } ! 1266: ! 1267: // ED:01000111: LD I,A ! 1268: OP_DEF(ld_i_a) ! 1269: { ! 1270: reg_i = reg.a; ! 1271: CYCLE(6); ! 1272: } ! 1273: ! 1274: // ED:01ww1010: ADC HL,ww ! 1275: OP_DEF(adc_hl_ww) ! 1276: { ! 1277: uint ww = (op >> 4) & 3; ! 1278: uint32 src = GetWW(ww); ! 1279: uint32 dst = reg.GetHL(); ! 1280: dst = ACC.adc_16(dst, src); ! 1281: reg.SetHL(dst); ! 1282: CYCLE(10); ! 1283: } ! 1284: ! 1285: // ED:01ww1011: LD ww,(nn) ! 1286: OP_DEF(ld_ww_nnin) ! 1287: { ! 1288: uint ww = (op >> 4) & 3; ! 1289: uint32 nn = Fetch16(); ! 1290: uint32 src = Read16(nn); ! 1291: SetWW(ww, src); ! 1292: CYCLE(18); ! 1293: } ! 1294: ! 1295: // ED:01ww1100: MLT ww (HD64*180 only) ! 1296: OP_DEF(mlt) ! 1297: { ! 1298: uint ww = (op >> 4) & 3; ! 1299: uint32 src = GetWW(ww); ! 1300: uint32 dst = (src >> 8) * (src & 0xff); ! 1301: SetWW(ww, dst); ! 1302: // フラグ変化なし ! 1303: CYCLE(17); ! 1304: } ! 1305: ! 1306: // ED:01001101: RETI ! 1307: OP_DEF(reti) ! 1308: { ! 1309: ops_ret(); ! 1310: CYCLE(12); ! 1311: } ! 1312: ! 1313: // ED:01001111: LD R,A ! 1314: OP_DEF(ld_r_a) ! 1315: { ! 1316: reg_r = reg.a; ! 1317: CYCLE(6); ! 1318: } ! 1319: ! 1320: // ED:01010110: IM 1 ! 1321: OP_DEF(im_1) ! 1322: { ! 1323: int0mode = 1; ! 1324: putlog(1, "IM %d", int0mode); ! 1325: CYCLE(6); ! 1326: } ! 1327: ! 1328: // ED:01010111: LD A,I ! 1329: OP_DEF(ld_a_i) ! 1330: { ! 1331: reg.a = ACC.ld_ir8(reg_i); ! 1332: ! 1333: // IEF2 を P/V にコピー。P でも V でもないので一応 V にしておく。 ! 1334: reg.f.SetV(GetIEF2()); ! 1335: ! 1336: // HD64180 ではこの命令の終わりで割り込みをサンプルしない。 ! 1337: intcheck = false; ! 1338: ! 1339: CYCLE(6); ! 1340: } ! 1341: ! 1342: // ED:01011110: IM 2 ! 1343: OP_DEF(im_2) ! 1344: { ! 1345: int0mode = 2; ! 1346: putlog(1, "IM %d", int0mode); ! 1347: CYCLE(6); ! 1348: } ! 1349: ! 1350: // ED:01011111: LD A,R ! 1351: OP_DEF(ld_a_r) ! 1352: { ! 1353: reg.a = ACC.ld_ir8(GetR()); ! 1354: ! 1355: // IEF2 を P/V にコピー。P でも V でもないので一応 V にしておく。 ! 1356: reg.f.SetV(GetIEF2()); ! 1357: ! 1358: // HD64180 ではこの命令の終わりで割り込みをサンプルしない。 ! 1359: intcheck = false; ! 1360: ! 1361: CYCLE(6); ! 1362: } ! 1363: ! 1364: // ED:01100100: TST n (HD64*180 only) ! 1365: OP_DEF(tst_n) ! 1366: { ! 1367: uint32 src = Fetch8(); ! 1368: ACC.and_8(reg.a, src); ! 1369: CYCLE(9); ! 1370: } ! 1371: ! 1372: // ED:01100111: RRD ! 1373: OP_DEF(rrd) ! 1374: { ! 1375: // +-----------+ +---+ ! 1376: // | v | v ! 1377: // +-----+-----+ +-----+-----+ ! 1378: // A | 7654 3210 | (HL) | 7654 3210 | ! 1379: // +-----+-----+ +-----+-----+ ! 1380: // ^ | ! 1381: // +-------------------+ ! 1382: ! 1383: uint32 hl = reg.GetHL(); ! 1384: uint32 m = Read8(hl); ! 1385: uint32 a = (reg.a & 0xf0) | (m & 0x0f); ! 1386: uint32 b = (reg.a << 4) | (m >> 4); ! 1387: Write8(hl, b); ! 1388: reg.a = ACC.in_8(a); ! 1389: CYCLE(16); ! 1390: } ! 1391: ! 1392: // ED:01101111: RLD ! 1393: OP_DEF(rld) ! 1394: { ! 1395: // +-------------------+ ! 1396: // | v ! 1397: // +-----+-----+ +-----+-----+ ! 1398: // A | 7654 3210 | (HL) | 7654 3210 | ! 1399: // +-----+-----+ +-----+-----+ ! 1400: // ^ | ^ | ! 1401: // +-----------+ +---+ ! 1402: ! 1403: uint32 hl = reg.GetHL(); ! 1404: uint32 m = Read8(hl); ! 1405: uint32 a = (reg.a & 0xf0) | (m >> 4); ! 1406: uint32 b = (m << 4) | (reg.a & 0x0f); ! 1407: Write8(hl, b); ! 1408: reg.a = ACC.in_8(a); ! 1409: CYCLE(16); ! 1410: } ! 1411: ! 1412: // ED:01110000: IN F,(C) ! 1413: OP_DEF(in_f_c) ! 1414: { ! 1415: // バスの上位には B が出る ! 1416: uint32 addr = reg.GetBC(); ! 1417: uint32 data = ReadIO(addr); ! 1418: ACC.in_8(data); ! 1419: CYCLE(9); ! 1420: } ! 1421: ! 1422: // ED:01110100: TSTIO n (HD64*180 only) ! 1423: OP_DEF(tstio_n) ! 1424: { ! 1425: // バスの上位は 0 になる ! 1426: uint32 n = Fetch8(); ! 1427: uint32 dst = ReadIO(reg.c); ! 1428: ACC.tst_8(dst, n); ! 1429: CYCLE(12); ! 1430: } ! 1431: ! 1432: // ED:01110110: SLP (HD64*180 only) ! 1433: OP_DEF(slp) ! 1434: { ! 1435: putlog(0, "SLP (NOT IMPLEMENTED)"); ! 1436: EnterSleep(); ! 1437: CYCLE(8); ! 1438: } ! 1439: ! 1440: // OTIM/OTDM の共通部分 ! 1441: void ! 1442: MPU64180Device::ops_otim(int inc) ! 1443: { ! 1444: uint32 hl = reg.GetHL(); ! 1445: uint32 src = Read8(hl); ! 1446: // バスの上位は 0 になる ! 1447: WriteIO(reg.c, src); ! 1448: reg.c += inc; ! 1449: hl += inc; ! 1450: reg.SetHL(hl); ! 1451: reg.b = ACC.outm_8(src, reg.b); ! 1452: CYCLE(14); ! 1453: } ! 1454: ! 1455: // ED:10000011: OTIM (HD64*180 only) ! 1456: OP_DEF(otim) ! 1457: { ! 1458: ops_otim(+1); ! 1459: } ! 1460: ! 1461: // ED:10001011: OTDM (HD64*180 only) ! 1462: OP_DEF(otdm) ! 1463: { ! 1464: ops_otim(-1); ! 1465: } ! 1466: ! 1467: // OTIMR/OTDMR の終了条件の共通部分。 ! 1468: // 他のリピート系命令とはフラグ変化が異なる。 ! 1469: void ! 1470: MPU64180Device::ops_otmr_until() ! 1471: { ! 1472: if (reg.b != 0) { ! 1473: reg.pc -= 2; ! 1474: CYCLE(2); ! 1475: } else { ! 1476: // 終了時はフラグ変化が違う。 ! 1477: // S:0 Z:1 H:0 P/V:1 N:* C:0 ! 1478: // このうち S, Z, H, N, C はセットされているままでよい。 ! 1479: // パリティだけセット。 ! 1480: reg.f.SetP(true); ! 1481: } ! 1482: } ! 1483: ! 1484: // ED:10010011: OTIMR (HD64*180 only) ! 1485: OP_DEF(otimr) ! 1486: { ! 1487: OP_FUNC(otim); ! 1488: ops_otmr_until(); ! 1489: } ! 1490: ! 1491: // ED:10011011: OTDMR (HD64*180 only) ! 1492: OP_DEF(otdmr) ! 1493: { ! 1494: OP_FUNC(otdm); ! 1495: ops_otmr_until(); ! 1496: } ! 1497: ! 1498: // LDI/LDD の共通部分 ! 1499: void ! 1500: MPU64180Device::ops_ldi(int inc) ! 1501: { ! 1502: uint32 hl = reg.GetHL(); ! 1503: uint32 de = reg.GetDE(); ! 1504: uint32 bc = reg.GetBC(); ! 1505: ! 1506: uint32 data = Read8(hl); ! 1507: Write8(de, data); ! 1508: hl += inc; ! 1509: de += inc; ! 1510: bc--; ! 1511: reg.SetHL(hl); ! 1512: reg.SetDE(de); ! 1513: reg.SetBC(bc); ! 1514: ! 1515: reg.f.SetV((bc != 0)); ! 1516: reg.f.SetN(false); ! 1517: reg.f.SetH(false); ! 1518: ! 1519: CYCLE(12); ! 1520: } ! 1521: ! 1522: // ED:10100000: LDI ! 1523: OP_DEF(ldi) ! 1524: { ! 1525: ops_ldi(+1); ! 1526: } ! 1527: ! 1528: // CPI/CPD の共通部分 ! 1529: void ! 1530: MPU64180Device::ops_cpi(int inc) ! 1531: { ! 1532: uint32 hl = reg.GetHL(); ! 1533: uint32 bc = reg.GetBC(); ! 1534: ! 1535: uint32 src = Read8(hl); ! 1536: ACC.sub_8(reg.a, src, true); ! 1537: hl += inc; ! 1538: bc--; ! 1539: reg.SetHL(hl); ! 1540: reg.SetBC(bc); ! 1541: ! 1542: reg.f.SetV(bc != 0); ! 1543: ! 1544: CYCLE(12); ! 1545: } ! 1546: ! 1547: // ED:10100001: CPI ! 1548: OP_DEF(cpi) ! 1549: { ! 1550: ops_cpi(+1); ! 1551: } ! 1552: ! 1553: // INI/IND の共通部分 ! 1554: void ! 1555: MPU64180Device::ops_ini(int inc) ! 1556: { ! 1557: uint32 hl = reg.GetHL(); ! 1558: // バスの上位には B が出る ! 1559: uint32 addr = reg.GetBC(); ! 1560: uint32 data = ReadIO(addr); ! 1561: Write8(hl, data); ! 1562: hl += inc; ! 1563: reg.b--; ! 1564: reg.SetHL(hl); ! 1565: // XXX S,H,P/V,C は本当は不定 ! 1566: reg.f.SetZ(reg.b == 0); ! 1567: reg.f.SetN((int8)data < 0); ! 1568: CYCLE(12); ! 1569: } ! 1570: ! 1571: // ED:10100010: INI ! 1572: OP_DEF(ini) ! 1573: { ! 1574: ops_ini(+1); ! 1575: } ! 1576: ! 1577: // OUTI/OUTD の共通部分 ! 1578: void ! 1579: MPU64180Device::ops_outi(int inc) ! 1580: { ! 1581: uint32 hl = reg.GetHL(); ! 1582: // バスの上位には B が出る ! 1583: uint32 addr = reg.GetBC(); ! 1584: uint32 data = Read8(hl); ! 1585: WriteIO(addr, data); ! 1586: hl += inc; ! 1587: reg.b--; ! 1588: reg.SetHL(hl); ! 1589: // XXX S,H,P/V,C は本当は不定 ! 1590: reg.f.SetZ(reg.b == 0); ! 1591: reg.f.SetN((int8)data < 0); ! 1592: CYCLE(12); ! 1593: } ! 1594: ! 1595: // ED:10100011: OUTI ! 1596: OP_DEF(outi) ! 1597: { ! 1598: ops_outi(+1); ! 1599: } ! 1600: ! 1601: // ED:10101000: LDD ! 1602: OP_DEF(ldd) ! 1603: { ! 1604: ops_ldi(-1); ! 1605: } ! 1606: ! 1607: // ED:10101001: CPD ! 1608: OP_DEF(cpd) ! 1609: { ! 1610: ops_cpi(-1); ! 1611: } ! 1612: ! 1613: // ED:10101010: IND ! 1614: OP_DEF(ind) ! 1615: { ! 1616: ops_ini(-1); ! 1617: } ! 1618: ! 1619: // ED:10101011: OUTD ! 1620: OP_DEF(outd) ! 1621: { ! 1622: ops_outi(-1); ! 1623: } ! 1624: ! 1625: // ED:10110000: LDIR ! 1626: OP_DEF(ldir) ! 1627: { ! 1628: REPEAT_UNTIL(ldi); ! 1629: } ! 1630: ! 1631: // ED:10110001: CPIR ! 1632: OP_DEF(cpir) ! 1633: { ! 1634: REPEAT_UNTIL(cpi); ! 1635: } ! 1636: ! 1637: // ED:10110010: INIR ! 1638: OP_DEF(inir) ! 1639: { ! 1640: REPEAT_UNTIL(ini); ! 1641: } ! 1642: ! 1643: // ED:10110011: OTIR ! 1644: OP_DEF(otir) ! 1645: { ! 1646: REPEAT_UNTIL(outi); ! 1647: } ! 1648: ! 1649: // ED:10111000: LDDR ! 1650: OP_DEF(lddr) ! 1651: { ! 1652: REPEAT_UNTIL(ldd); ! 1653: } ! 1654: ! 1655: // ED:10111001: CPDR ! 1656: OP_DEF(cpdr) ! 1657: { ! 1658: REPEAT_UNTIL(cpd); ! 1659: } ! 1660: ! 1661: // ED:10111010: INDR ! 1662: OP_DEF(indr) ! 1663: { ! 1664: REPEAT_UNTIL(ind); ! 1665: } ! 1666: ! 1667: // ED:10111011: OTDR ! 1668: OP_DEF(otdr) ! 1669: { ! 1670: REPEAT_UNTIL(outd); ! 1671: } ! 1672: ! 1673: // ED:11rrr001: MULUB A,r (R800 only) ! 1674: OP_DEF(mulub_a_r) ! 1675: { ! 1676: op_illegal(2); ! 1677: } ! 1678: ! 1679: // ED:11000011: MULUB HL,BC (R800 only) ! 1680: OP_DEF(mulub_hl_bc) ! 1681: { ! 1682: op_illegal(2); ! 1683: } ! 1684: ! 1685: // ED:11110011: MULUB HL,SP (R800 only) ! 1686: OP_DEF(mulub_hl_sp) ! 1687: { ! 1688: op_illegal(2); ! 1689: } ! 1690: ! 1691: // ED:11111111: SYSCALL (HD64*180 only) ! 1692: OP_DEF(syscall) ! 1693: { ! 1694: // MSX-DOS エミュレーションのような何か。 ! 1695: // 通常の DOSCALL と同様、コール番号は C レジスタに入っている。 ! 1696: ! 1697: if (gMainApp.msxdos_mode) { ! 1698: // MSX-DOS エミュレーションなら DOS コールを処理する ! 1699: assert(syscall_callback != NULL); ! 1700: syscall_callback(syscall_arg); ! 1701: CYCLE(3); ! 1702: } else { ! 1703: // 通常時は他の ED 系列と同じく不当命令例外。 ! 1704: op_illegal(2); ! 1705: } ! 1706: } ! 1707: ! 1708: // DD:00rrr100: INC ixr (Z80/R800) ! 1709: OP_DEF(inc_ixr) ! 1710: { ! 1711: op_illegal(2); ! 1712: } ! 1713: ! 1714: // DD:00rrr101: DEC ixr (Z80/R800) ! 1715: OP_DEF(dec_ixr) ! 1716: { ! 1717: op_illegal(2); ! 1718: } ! 1719: ! 1720: // DD:01rrrsss: LD r,ixs (Z80/R800) ! 1721: OP_DEF(ld_r_ixs) ! 1722: { ! 1723: op_illegal(2); ! 1724: } ! 1725: ! 1726: // DD:10000rrr: ADD A,ixr (Z80/R800) ! 1727: OP_DEF(add_a_ixr) ! 1728: { ! 1729: op_illegal(2); ! 1730: } ! 1731: ! 1732: // DD:10001rrr: ADC A,ixr (Z80/R800) ! 1733: OP_DEF(adc_a_ixr) ! 1734: { ! 1735: op_illegal(2); ! 1736: } ! 1737: ! 1738: // DD:10010rrr: SUB ixr (Z80/R800) ! 1739: OP_DEF(sub_ixr) ! 1740: { ! 1741: op_illegal(2); ! 1742: } ! 1743: ! 1744: // DD:10011rrr: SBC A,ixr (Z80/R800) ! 1745: OP_DEF(sbc_a_ixr) ! 1746: { ! 1747: op_illegal(2); ! 1748: } ! 1749: ! 1750: // DD:10100rrr: AND ixr (Z80/R800) ! 1751: OP_DEF(and_ixr) ! 1752: { ! 1753: op_illegal(2); ! 1754: } ! 1755: ! 1756: // DD:10101rrr: XOR ixr (Z80/R800) ! 1757: OP_DEF(xor_ixr) ! 1758: { ! 1759: op_illegal(2); ! 1760: } ! 1761: ! 1762: // DD:10110rrr: OR ixr (Z80/R800) ! 1763: OP_DEF(or_ixr) ! 1764: { ! 1765: op_illegal(2); ! 1766: } ! 1767: ! 1768: // DD:10111rrr: CP ixr (Z80/R800) ! 1769: OP_DEF(cp_ixr) ! 1770: { ! 1771: op_illegal(2); ! 1772: } ! 1773: ! 1774: // DD:11001011: op_DD_CB ! 1775: OP_DEF(dd_cb) ! 1776: { ! 1777: // DD CB の場合は 3バイト目が d で、4バイト目が命令語。 ! 1778: ixd = Fetch8(); ! 1779: ! 1780: // 4バイト目をフェッチ ! 1781: op = Fetch8(); ! 1782: ! 1783: // で分岐 ! 1784: switch (op) { ! 1785: #include "hd64180switch_dd_cb.inc" ! 1786: default: ! 1787: op_illegal(3); ! 1788: break; ! 1789: } ! 1790: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.