Annotation of nono/hd64180/hd64180ops.cpp, revision 1.1

1.1     ! root        1: #include "hd64180acc.h"
        !             2: 
        !             3: #define ACC (*(hd64180acc*)&reg.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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.