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