Annotation of nono/m680x0/m68030ops.cpp, revision 1.1.1.5

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.5 ! root        7: #include "mpu680x0.h"
        !             8: #include "m68030acc.h"
        !             9: #include "m68030bitfield.h"
        !            10: 
        !            11: #define OP_DEF(name)   void __CONCAT(MPU680x0Device::op_,name)()
        !            12: #define OP_FUNC(name)  __CONCAT(op_,name)()
        !            13: 
        !            14: #define CCR reg.ccr
        !            15: #define ACC (*(m68030acc*)&reg.ccr)
        !            16: 
        !            17: #define RegIRX                 ((ir >> 9) & 7)
        !            18: #define RegIRY                 (ir & 7)
        !            19: #define RegDX                  reg.D[RegIRX]
        !            20: #define RegAX                  reg.A[RegIRX]
        !            21: #define RegDY                  reg.D[RegIRY]
        !            22: #define RegAY                  reg.A[RegIRY]
        !            23: 
        !            24: // 副作用のあるマクロ
        !            25: // 特権違反例外のスタックに積む PC は違反を起こした命令先頭。
        !            26: #define SUPERVISOR_OP  do { \
        !            27:        if (!IsSuper()) {       \
        !            28:                CYCLE2(18, 20); \
        !            29:                Exception(M68K::EXCEP_PRIV);    \
        !            30:                return; \
        !            31:        }       \
        !            32: } while (0)
        !            33: 
        !            34: // FPU 命令の FSAVE/FRESTORE 以外のグループ全員で実行開始時に必要な処理
        !            35: inline void
        !            36: MPU680x0Device::fpu_op_start()
        !            37: {
        !            38:        fpu_dirty = true;
        !            39: 
        !            40:        // 現在の FPCR/FPSR を fe 構造体にコピー。
        !            41:        //
        !            42:        // fe.fe_{fpcr,fpsr} のほうはこの fpe 用の内部ワークなので破壊してよい。
        !            43:        // 命令実行の結果、FPSR レジスタの値を更新する際は fpu_upd_fpsr() を
        !            44:        // 呼ぶこと。これを使わず独自に更新する場合は fe.fe_fpframe->fpf_fpsr
        !            45:        // (こっちがレジスタ値) と fe.fe_fpsr (FPE 用) を同時に更新すること。
        !            46:        // FPCR のほうは FMOVE-to-FPCR 命令以外で変更されることはないはず。
        !            47:        fe.fe_fpcr = RegFPCR;
        !            48:        fe.fe_fpsr = RegFPSR;
        !            49: }
        !            50: 
1.1       root       51: // %0000_000000_mmmrrr ORI.B #<imm>,<ea>
                     52: // %0000_000000_111100 ORI.B #<imm>,CCR
                     53: OP_DEF(ori_b)
                     54: {
1.1.1.5 ! root       55:        uint n = ir & 0x3f;
1.1       root       56: 
1.1.1.5 ! root       57:        uint32 src = fetch_16() & 0xff;
1.1       root       58:        if (n < 8) {
                     59:                // ORI.B #<imm>,Dn
                     60:                CYCLE(2);
1.1.1.5 ! root       61:                uint32 dst = (reg.D[n] & 0xff) | src;
        !            62:                ACC.move_8(dst);
        !            63:                reg.D[n] = (reg.D[n] & 0xffffff00) | dst;
1.1       root       64:        } else if (n == 0b111100) {
                     65:                // ORI.B #<imm>,SR
                     66:                CYCLE2(12, 14);
                     67:                CCR.Set(CCR.Get() | src);
                     68:        } else {
                     69:                // ORI.B #<imm>,<ea>
                     70:                CYCLE2(3, 4);
1.1.1.5 ! root       71:                uint32 ea = cea_data_8();
        !            72:                uint32 dst = read_8(ea);
1.1       root       73:                dst |= src;
1.1.1.5 ! root       74:                ACC.move_8(dst);
        !            75:                write_8(ea, dst);
1.1       root       76:        }
                     77: }
                     78: 
                     79: // %0000_000001_mmmrrr ORI.W #<imm>,<ea>
                     80: // %0000_000001_111100 ORI.W #<imm>,SR
                     81: OP_DEF(ori_w)
                     82: {
1.1.1.5 ! root       83:        uint n = ir & 0x3f;
1.1       root       84: 
                     85:        if (n < 8) {
                     86:                // ORI.W #<imm>,Dn
                     87:                CYCLE(2);
1.1.1.5 ! root       88:                uint32 src = fetch_16();
        !            89:                uint32 dst = (reg.D[n] & 0xffff) | src;
        !            90:                ACC.move_16(dst);
        !            91:                reg.D[n] = (reg.D[n] & 0xffff0000) | dst;
1.1       root       92:        } else if (n == 0b111100) {
                     93:                // ORI.W #<imm>,SR
                     94:                SUPERVISOR_OP;
                     95:                CYCLE2(12, 14);
1.1.1.5 ! root       96:                uint32 src = fetch_16();
        !            97:                SetSR(GetSR() | src);
1.1       root       98:        } else {
                     99:                // ORI.W #<imm>,<ea>
                    100:                CYCLE2(3, 4);
1.1.1.5 ! root      101:                uint32 src = fetch_16();
        !           102:                uint32 ea = cea_data_16();
        !           103:                uint32 dst = read_16(ea);
1.1       root      104:                dst |= src;
1.1.1.5 ! root      105:                ACC.move_16(dst);
        !           106:                write_16(ea, dst);
1.1       root      107:        }
                    108: }
                    109: 
                    110: // %0000_000010_mmmrrr ORI.L #<imm>,<ea>
                    111: OP_DEF(ori_l)
                    112: {
1.1.1.5 ! root      113:        uint n = ir & 0x3f;
1.1       root      114: 
1.1.1.5 ! root      115:        uint32 src = fetch_32();
1.1       root      116:        if (n < 8) {
                    117:                // ORI.L #<imm>,Dn
                    118:                CYCLE(2);
1.1.1.5 ! root      119:                reg.D[n] |= src;
        !           120:                ACC.move_32(reg.D[n]);
1.1       root      121:        } else {
                    122:                // ORI.L #<imm>,<ea>
                    123:                CYCLE2(3, 4);
1.1.1.5 ! root      124:                uint32 ea = cea_data_32();
        !           125:                uint32 dst = read_32(ea);
1.1       root      126:                dst |= src;
1.1.1.5 ! root      127:                ACC.move_32(dst);
        !           128:                write_32(ea, dst);
1.1       root      129:        }
                    130: }
                    131: 
                    132: // %0000_000011_mmmrrr CMP2/CHK2.B <ea>,Rn
                    133: OP_DEF(cmp2chk2_b)
                    134: {
1.1.1.5 ! root      135:        ir2 = fetch_16();
1.1       root      136:        uint32 compare;
1.1.1.5 ! root      137:        uint32 ea = cea_ctrl();
1.1       root      138:        uint32 lower;
                    139:        uint32 upper;
                    140: 
1.1.1.5 ! root      141:        if ((ir2 & 0x8000) == 0) {
1.1       root      142:                // compare が Dn
1.1.1.5 ! root      143:                compare = (int32)(int8)(reg.R[ir2 >> 12] & 0xff);
1.1       root      144:        } else {
                    145:                // compare が An
1.1.1.5 ! root      146:                compare = reg.R[ir2 >> 12];
1.1       root      147:        }
                    148: 
                    149:        // 本当は PC 相対ならプログラム空間アクセス、
                    150:        // それ以外はデータ空間アクセスだが、ここでは区別しない。
1.1.1.5 ! root      151:        lower = (int32)(int8)read_8(ea);
        !           152:        upper = (int32)(int8)read_8(ea + 1);
1.1       root      153: 
1.1.1.5 ! root      154:        ACC.chk2cmp2_32(compare, lower, upper);
1.1       root      155: 
                    156:        // サイクル数はこれは実際には全部最大値
1.1.1.5 ! root      157:        if ((ir2 & 0x0800)) {
1.1       root      158:                // CHK2 で条件を満たしていれば例外
1.1.1.5 ! root      159:                if (reg.ccr.CondCS()) {
1.1       root      160:                        CYCLE2(40, 42);
1.1.1.5 ! root      161:                        Exception(M68K::EXCEP_CHK);
1.1       root      162:                } else {
                    163:                        CYCLE(18);
                    164:                }
                    165:        } else {
                    166:                // CMP2
                    167:                CYCLE(20);
                    168:        }
                    169: }
                    170: 
                    171: // MOVEP.[WL] (d,Ay),Dx と
                    172: // MOVEP.[WL] Dx,(d,Ay) の共通部分。
1.1.1.5 ! root      173: void
        !           174: MPU680x0Device::ops_movep()
1.1       root      175: {
1.1.1.5 ! root      176:        uint32 disp = (int32)(int16)fetch_16();
1.1       root      177:        uint32 ea = RegAY + disp;
1.1.1.5 ! root      178:        bool size_long = ((ir & 0x40) != 0);
        !           179:        bool reg2mem = ((ir & 0x80) != 0);
1.1       root      180: 
                    181:        CYCLE(14);
                    182: 
                    183:        if (reg2mem) {
                    184:                // Dx -> memory
                    185:                uint32 dx = RegDX;
                    186:                if (size_long) {
1.1.1.5 ! root      187:                        write_8(ea, (dx >> 24));
1.1       root      188:                        ea += 2;
1.1.1.5 ! root      189:                        write_8(ea, (dx >> 16) & 0xff);
1.1       root      190:                        ea += 2;
                    191:                }
1.1.1.5 ! root      192:                write_8(ea, (dx >> 8) & 0xff);
1.1       root      193:                ea += 2;
1.1.1.5 ! root      194:                write_8(ea, (dx & 0xff));
1.1       root      195:        } else {
                    196:                // memory -> Dx
                    197:                uint32 dx = 0;
                    198:                if (size_long) {
1.1.1.5 ! root      199:                        dx = read_8(ea);
1.1       root      200:                        dx <<= 8;
                    201:                        ea += 2;
1.1.1.5 ! root      202:                        dx |= read_8(ea);
1.1       root      203:                        dx <<= 8;
                    204:                        ea += 2;
                    205:                }
                    206:                // word
1.1.1.5 ! root      207:                dx |= read_8(ea);
1.1       root      208:                dx <<= 8;
                    209:                ea += 2;
1.1.1.5 ! root      210:                dx |= read_8(ea);
1.1       root      211: 
                    212:                if (size_long) {
                    213:                        RegDX = dx;
                    214:                } else {
                    215:                        RegDX = (RegDX & 0xffff0000) | (dx & 0xffff);
                    216:                }
                    217:        }
                    218: }
                    219: 
                    220: // %0000_xxx100_000yyy BTST.L Dx,Dy
                    221: // %0000_xxx100_001yyy MOVEP.W (d,Ay),Dx
                    222: // %0000_xxx100_mmmrrr BTST.B Dx,<ea>
                    223: OP_DEF(btst_dn_ea)
                    224: {
1.1.1.5 ! root      225:        uint n = ir & 0x3f;
1.1       root      226: 
                    227:        if (n < 8) {
                    228:                // BTST.L Dx,Dy
                    229:                CYCLE(4);
                    230:                uint bit = (RegDX & 31);
1.1.1.5 ! root      231:                ACC.btst(RegDY, bit);
1.1       root      232:        } else if (n < 16) {
                    233:                // MOVEP.W (d,Ay),Dx
1.1.1.5 ! root      234:                ops_movep();
1.1       root      235:        } else {
                    236:                // BTST.B Dx,<ea>
                    237:                CYCLE(4);
                    238:                uint bit = (RegDX & 7);
1.1.1.5 ! root      239:                uint32 data = fea_data_8();
        !           240:                ACC.btst(data, bit);
1.1       root      241:        }
                    242: }
                    243: 
                    244: // %0000_xxx101_000yyy BCHG.L Dx,Dy
                    245: // %0000_xxx101_001yyy MOVEP.L (d,Ay),Dx
                    246: // %0000_xxx101_mmmrrr BCHG.B Dx,<ea>
                    247: OP_DEF(bchg_dn_ea)
                    248: {
1.1.1.5 ! root      249:        uint n = ir & 0x3f;
1.1       root      250: 
                    251:        if (n < 8) {
                    252:                // BCHG.L Dx,Dy
                    253:                CYCLE(6);
                    254:                uint bit = (RegDX & 31);
1.1.1.5 ! root      255:                RegDY = ACC.bchg(RegDY, bit);
1.1       root      256:        } else if (n < 16) {
                    257:                // MOVEP.L (d,Ay),Dx
1.1.1.5 ! root      258:                ops_movep();
1.1       root      259:        } else {
                    260:                // BCHG.B Dx,<ea>
                    261:                CYCLE(6);
                    262:                uint bit = (RegDX & 7);
1.1.1.5 ! root      263:                uint32 ea = cea_data_8();
        !           264:                uint32 data = read_8(ea);
        !           265:                data = ACC.bchg(data, bit);
        !           266:                write_8(ea, data);
1.1       root      267:        }
                    268: }
                    269: 
                    270: // %0000_xxx110_000yyy BCLR.L Dx,Dy
                    271: // %0000_xxx110_001yyy MOVEP.W Dx,(d,Ay)
                    272: // %0000_xxx110_mmmrrr BCLR.B Dx,<ea>
                    273: OP_DEF(bclr_dn_ea)
                    274: {
1.1.1.5 ! root      275:        uint n = ir & 0x3f;
1.1       root      276: 
                    277:        if (n < 8) {
                    278:                // BCLR.L Dx,Dy
                    279:                CYCLE(6);
                    280:                uint bit = (RegDX & 31);
1.1.1.5 ! root      281:                RegDY = ACC.bclr(RegDY, bit);
1.1       root      282:        } else if (n < 16) {
                    283:                // MOVEP.W Dx,(d,Ay)
1.1.1.5 ! root      284:                ops_movep();
1.1       root      285:        } else {
                    286:                // BCLR.B Dx,<ea>
                    287:                CYCLE(6);
                    288:                uint bit = (RegDX & 7);
1.1.1.5 ! root      289:                uint32 ea = cea_data_8();
        !           290:                uint32 data = read_8(ea);
        !           291:                data = ACC.bclr(data, bit);
        !           292:                write_8(ea, data);
1.1       root      293:        }
                    294: }
                    295: 
                    296: // %0000_xxx111_000yyy BSET.L Dx,Dy
                    297: // %0000_xxx111_001yyy MOVEP.L Dx,(d,Ay)
                    298: // %0000_xxx111_mmmrrr BSET.B Dx,<ea>
                    299: OP_DEF(bset_dn_ea)
                    300: {
1.1.1.5 ! root      301:        uint n = ir & 0x3f;
1.1       root      302: 
                    303:        if (n < 8) {
                    304:                // BSET.L Dx,Dy
                    305:                CYCLE(6);
                    306:                uint bit = (RegDX & 31);
1.1.1.5 ! root      307:                RegDY = ACC.bset(RegDY, bit);
1.1       root      308:        } else if (n < 16) {
                    309:                // MOVEP.L Dx,(d,Ay)
1.1.1.5 ! root      310:                ops_movep();
1.1       root      311:        } else {
                    312:                // BSET.B Dx,<ea>
                    313:                CYCLE(6);
                    314:                uint bit = (RegDX & 7);
1.1.1.5 ! root      315:                uint32 ea = cea_data_8();
        !           316:                uint32 data = read_8(ea);
        !           317:                data = ACC.bset(data, bit);
        !           318:                write_8(ea, data);
1.1       root      319:        }
                    320: }
                    321: 
                    322: // %0000_001000_mmmrrr ANDI.B #<imm>,<ea>
                    323: // %0000_001000_111100 ANDI.B #<imm>,CCR
                    324: OP_DEF(andi_b)
                    325: {
1.1.1.5 ! root      326:        uint n = ir & 0x3f;
1.1       root      327: 
1.1.1.5 ! root      328:        uint32 src = fetch_16() & 0xff;
1.1       root      329:        if (n < 8) {
                    330:                // ANDI.B #<imm>,Dn
                    331:                CYCLE(2);
1.1.1.5 ! root      332:                uint32 dst = reg.D[n] & 0xff;
1.1       root      333:                dst &= src;
1.1.1.5 ! root      334:                ACC.move_8(dst);
        !           335:                reg.D[n] = (reg.D[n] & 0xffffff00) | dst;
1.1       root      336:        } else if (n == 0b111100) {
                    337:                // ANDI.B #<imm>,CCR
                    338:                CYCLE2(12, 14);
                    339:                CCR.Set(CCR.Get() & src);
                    340:        } else {
                    341:                // ANDI.B #<imm>,<ea>
                    342:                CYCLE2(3, 4);
1.1.1.5 ! root      343:                uint32 ea = cea_data_8();
        !           344:                uint32 dst = read_8(ea);
1.1       root      345:                dst &= src;
1.1.1.5 ! root      346:                ACC.move_8(dst);
        !           347:                write_8(ea, dst);
1.1       root      348:        }
                    349: }
                    350: 
                    351: // %0000_001001_mmmrrr ANDI.W #<imm>,<ea>
                    352: // %0000_001001_111100 ANDI.W #<imm>,SR
                    353: OP_DEF(andi_w)
                    354: {
1.1.1.5 ! root      355:        uint n = ir & 0x3f;
1.1       root      356: 
                    357:        if (n < 8) {
                    358:                // ANDI.W #<imm>,Dn
                    359:                CYCLE(2);
1.1.1.5 ! root      360:                uint32 src = fetch_16();
        !           361:                uint32 dst = reg.D[n] & 0xffff;
1.1       root      362:                dst &= src;
1.1.1.5 ! root      363:                ACC.move_16(dst);
        !           364:                reg.D[n] = (reg.D[n] & 0xffff0000) | dst;
1.1       root      365:        } else if (n == 0b111100) {
                    366:                // ANDI.W #<imm>,SR
                    367:                SUPERVISOR_OP;
                    368:                CYCLE2(12, 14);
1.1.1.5 ! root      369:                uint32 src = fetch_16();
        !           370:                SetSR(GetSR() & src);
1.1       root      371:        } else {
                    372:                // ANDI.W #<imm>,<ea>
                    373:                CYCLE2(3, 4);
1.1.1.5 ! root      374:                uint32 src = fetch_16();
        !           375:                uint32 ea = cea_data_16();
        !           376:                uint32 dst = read_16(ea);
1.1       root      377:                dst &= src;
1.1.1.5 ! root      378:                ACC.move_16(dst);
        !           379:                write_16(ea, dst);
1.1       root      380:        }
                    381: }
                    382: 
                    383: // %0000_001010_mmmrrr ANDI.L #<imm>,<ea>
                    384: OP_DEF(andi_l)
                    385: {
1.1.1.5 ! root      386:        uint n = ir & 0x3f;
1.1       root      387: 
1.1.1.5 ! root      388:        uint32 src = fetch_32();
1.1       root      389:        if (n < 8) {
                    390:                // ANDI.L #<imm>,Dn
                    391:                CYCLE(2);
1.1.1.5 ! root      392:                reg.D[n] &= src;
        !           393:                ACC.move_32(reg.D[n]);
1.1       root      394:        } else {
                    395:                // ANDI.L #<imm>,<ea>
                    396:                CYCLE2(3, 4);
1.1.1.5 ! root      397:                uint32 ea = cea_data_32();
        !           398:                uint32 dst = read_32(ea);
1.1       root      399:                dst &= src;
1.1.1.5 ! root      400:                ACC.move_32(dst);
        !           401:                write_32(ea, dst);
1.1       root      402:        }
                    403: }
                    404: 
                    405: // %0000_001011_mmmrrr CMP2/CHK2.W <ea>,Rn
                    406: OP_DEF(cmp2chk2_w)
                    407: {
1.1.1.5 ! root      408:        ir2 = fetch_16();
1.1       root      409:        uint32 compare;
1.1.1.5 ! root      410:        uint32 ea = cea_ctrl();
1.1       root      411:        uint32 lower;
                    412:        uint32 upper;
                    413: 
1.1.1.5 ! root      414:        if ((ir2 & 0x8000) == 0) {
1.1       root      415:                // compare が Dn
1.1.1.5 ! root      416:                compare = (int32)(int16)(reg.R[ir2 >> 12] & 0xffff);
1.1       root      417:        } else {
                    418:                // compare が An
1.1.1.5 ! root      419:                compare = reg.R[ir2 >> 12];
1.1       root      420:        }
                    421: 
                    422:        // 本当は PC 相対ならプログラム空間アクセス、
                    423:        // それ以外はデータ空間アクセスだが、ここでは区別しない。
1.1.1.5 ! root      424:        lower = (int32)(int16)read_16(ea);
        !           425:        upper = (int32)(int16)read_16(ea + 2);
1.1       root      426: 
1.1.1.5 ! root      427:        ACC.chk2cmp2_32(compare, lower, upper);
1.1       root      428: 
                    429:        // サイクル数はこれは実際には全部最大値
1.1.1.5 ! root      430:        if ((ir2 & 0x0800)) {
1.1       root      431:                // CHK2 で条件を満たしていれば例外
1.1.1.5 ! root      432:                if (reg.ccr.CondCS()) {
1.1       root      433:                        CYCLE2(40, 42);
1.1.1.5 ! root      434:                        Exception(M68K::EXCEP_CHK);
1.1       root      435:                } else {
                    436:                        CYCLE(18);
                    437:                }
                    438:        } else {
                    439:                // CMP2
                    440:                CYCLE(20);
                    441:        }
                    442: }
                    443: 
                    444: // %0000_010000_mmmrrr SUBI.B #<imm>,<ea>
                    445: OP_DEF(subi_b)
                    446: {
1.1.1.5 ! root      447:        uint n = ir & 0x3f;
1.1       root      448: 
1.1.1.5 ! root      449:        uint32 src = fetch_16() & 0xff;
1.1       root      450:        if (n < 8) {
                    451:                // SUBI.B #<imm>,Dn
                    452:                CYCLE(2);
1.1.1.5 ! root      453:                uint32 dst = reg.D[n] & 0xff;
        !           454:                dst = ACC.sub_8(src, dst);
        !           455:                reg.D[n] = (reg.D[n] & 0xffffff00) | dst;
1.1       root      456:        } else {
                    457:                // SUBI.B #<imm>,<ea>
                    458:                CYCLE2(3, 4);
1.1.1.5 ! root      459:                uint32 ea = cea_data_8();
        !           460:                uint32 dst = read_8(ea);
        !           461:                dst = ACC.sub_8(src, dst);
        !           462:                write_8(ea, dst);
1.1       root      463:        }
                    464: }
                    465: 
                    466: // %0000_010001_mmmrrr SUBI.W #<imm>,<ea>
                    467: OP_DEF(subi_w)
                    468: {
1.1.1.5 ! root      469:        uint n = ir & 0x3f;
1.1       root      470: 
1.1.1.5 ! root      471:        uint32 src = fetch_16();
1.1       root      472:        if (n < 8) {
                    473:                // SUBI.W #<imm>,Dn
                    474:                CYCLE(2);
1.1.1.5 ! root      475:                uint32 dst = reg.D[n] & 0xffff;
        !           476:                dst = ACC.sub_16(src, dst);
        !           477:                reg.D[n] = (reg.D[n] & 0xffff0000) | dst;
1.1       root      478:        } else {
                    479:                // SUBI.W #<imm>,<ea>
                    480:                CYCLE2(3, 4);
1.1.1.5 ! root      481:                uint32 ea = cea_data_16();
        !           482:                uint32 dst = read_16(ea);
        !           483:                dst = ACC.sub_16(src, dst);
        !           484:                write_16(ea, dst);
1.1       root      485:        }
                    486: }
                    487: 
                    488: // %0000_010010_mmmrrr SUBI.L #<imm>,<ea>
                    489: OP_DEF(subi_l)
                    490: {
1.1.1.5 ! root      491:        uint n = ir & 0x3f;
1.1       root      492: 
1.1.1.5 ! root      493:        uint32 src = fetch_32();
1.1       root      494:        if (n < 8) {
                    495:                // SUBI.L #<imm>,Dn
                    496:                CYCLE(2);
1.1.1.5 ! root      497:                reg.D[n] = ACC.sub_32(src, reg.D[n]);
1.1       root      498:        } else {
                    499:                // SUBI.L #<imm>,<ea>
                    500:                CYCLE2(3, 4);
1.1.1.5 ! root      501:                uint32 ea = cea_data_32();
        !           502:                uint32 dst = read_32(ea);
        !           503:                dst = ACC.sub_32(src, dst);
        !           504:                write_32(ea, dst);
1.1       root      505:        }
                    506: }
                    507: 
                    508: // %0000_010011_mmmrrr CMP2/CHK2.L <ea>,Rn
                    509: OP_DEF(cmp2chk2_l)
                    510: {
1.1.1.5 ! root      511:        ir2 = fetch_16();
        !           512:        uint32 compare = reg.R[ir2 >> 12];
        !           513:        uint32 ea = cea_ctrl();
1.1       root      514:        uint32 lower;
                    515:        uint32 upper;
                    516: 
                    517:        // 本当は PC 相対ならプログラム空間アクセス、
                    518:        // それ以外はデータ空間アクセスだが、ここでは区別しない。
1.1.1.5 ! root      519:        lower = read_32(ea);
        !           520:        upper = read_32(ea + 4);
1.1       root      521: 
1.1.1.5 ! root      522:        ACC.chk2cmp2_32(compare, lower, upper);
1.1       root      523: 
                    524:        // サイクル数はこれは実際には全部最大値
1.1.1.5 ! root      525:        if ((ir2 & 0x0800)) {
1.1       root      526:                // CHK2 で条件を満たしていれば例外
1.1.1.5 ! root      527:                if (reg.ccr.CondCS()) {
1.1       root      528:                        CYCLE2(40, 42);
1.1.1.5 ! root      529:                        Exception(M68K::EXCEP_CHK);
1.1       root      530:                } else {
                    531:                        CYCLE(18);
                    532:                }
                    533:        } else {
                    534:                // CMP2
                    535:                CYCLE(20);
                    536:        }
                    537: }
                    538: 
                    539: // %0000_011000_mmmrrr ADDI.B #<imm>,<ea>
                    540: OP_DEF(addi_b)
                    541: {
1.1.1.5 ! root      542:        uint n = ir & 0x3f;
1.1       root      543: 
1.1.1.5 ! root      544:        uint32 src = fetch_16() & 0xff;
1.1       root      545:        if (n < 8) {
                    546:                // ADDI.B #<imm>,Dn
                    547:                CYCLE(2);
1.1.1.5 ! root      548:                uint32 dst = reg.D[n] & 0xff;
        !           549:                dst = ACC.add_8(src, dst);
        !           550:                reg.D[n] = (reg.D[n] & 0xffffff00) | dst;
1.1       root      551:        } else {
                    552:                // ADDI.B #<imm>,<ea>
                    553:                CYCLE2(3, 4);
1.1.1.5 ! root      554:                uint32 ea = cea_data_8();
        !           555:                uint32 dst = read_8(ea);
        !           556:                dst = ACC.add_8(src, dst);
        !           557:                write_8(ea, dst);
1.1       root      558:        }
                    559: }
                    560: 
                    561: // %0000_011001_mmmrrr ADDI.W #<imm>,<ea>
                    562: OP_DEF(addi_w)
                    563: {
1.1.1.5 ! root      564:        uint n = ir & 0x3f;
1.1       root      565: 
1.1.1.5 ! root      566:        uint32 src = fetch_16();
1.1       root      567:        if (n < 8) {
                    568:                // ADDI.W #<imm>,Dn
                    569:                CYCLE(2);
1.1.1.5 ! root      570:                uint32 dst = reg.D[n] & 0xffff;
        !           571:                dst = ACC.add_16(src, dst);
        !           572:                reg.D[n] = (reg.D[n] & 0xffff0000) | dst;
1.1       root      573:        } else {
                    574:                // ADDI.W #<imm>,<ea>
                    575:                CYCLE2(3, 4);
1.1.1.5 ! root      576:                uint32 ea = cea_data_16();
        !           577:                uint32 dst = read_16(ea);
        !           578:                dst = ACC.add_16(src, dst);
        !           579:                write_16(ea, dst);
1.1       root      580:        }
                    581: }
                    582: 
                    583: // %0000_011010_mmmrrr ADDI.L #<imm>,<ea>
                    584: OP_DEF(addi_l)
                    585: {
1.1.1.5 ! root      586:        uint n = ir & 0x3f;
1.1       root      587: 
1.1.1.5 ! root      588:        uint32 src = fetch_32();
1.1       root      589:        if (n < 8) {
                    590:                // ADDI.L #<imm>,Dn
                    591:                CYCLE(2);
1.1.1.5 ! root      592:                reg.D[n] = ACC.add_32(src, reg.D[n]);
1.1       root      593:        } else {
                    594:                // ADDI.L #<imm>,<ea>
                    595:                CYCLE2(3, 4);
1.1.1.5 ! root      596:                uint32 ea = cea_data_32();
        !           597:                uint32 dst = read_32(ea);
        !           598:                dst = ACC.add_32(src, dst);
        !           599:                write_32(ea, dst);
1.1       root      600:        }
                    601: }
                    602: 
1.1.1.3   root      603: // %0000_011011_00nnnn RTM Rn
                    604: // %0000_011011_mmmrrr CALLM #<imm>,<ea>
                    605: OP_DEF(callm)
                    606: {
1.1.1.5 ! root      607:        op_illegal();
1.1.1.3   root      608: }
                    609: 
1.1       root      610: // %0000_100000_000yyy BTST.L #<imm>,Dy
                    611: // %0000_100000_mmmrrr BTST.B #<imm>,<ea>
                    612: OP_DEF(btst_imm_ea)
                    613: {
1.1.1.5 ! root      614:        uint n = ir & 0x3f;
1.1       root      615: 
                    616:        if (n < 8) {
                    617:                // BTST.L #<imm>,Dy
                    618:                CYCLE(4);
1.1.1.5 ! root      619:                uint bit = fetch_16() & 31;
        !           620:                ACC.btst(RegDY, bit);
1.1       root      621:        } else if (n == 0x3c) {
                    622:                // BTST.B #<imm>,<ea> の <ea> には #imm はない
1.1.1.5 ! root      623:                op_illegal();
1.1       root      624:        } else {
                    625:                // BTST.B #<imm>,<ea>
                    626:                CYCLE(4);
1.1.1.5 ! root      627:                uint bit = fetch_16() & 7;
        !           628:                uint32 data = fea_data_8();
        !           629:                ACC.btst(data, bit);
1.1       root      630:        }
                    631: }
                    632: 
                    633: // %0000_100001_000yyy BCHG.L #<imm>,Dy
                    634: // %0000_100001_mmmrrr BCHG.B #<imm>,<ea>
                    635: OP_DEF(bchg_imm_ea)
                    636: {
1.1.1.5 ! root      637:        uint n = ir & 0x3f;
1.1       root      638: 
                    639:        if (n < 8) {
                    640:                // BCHG.L #<imm>,Dy
                    641:                CYCLE(6);
1.1.1.5 ! root      642:                uint bit = fetch_16() & 31;
        !           643:                RegDY = ACC.bchg(RegDY, bit);
1.1       root      644:        } else if (n == 0x3c) {
                    645:                // BCHG.B #<imm>,<ea> の <ea> には #imm はない
1.1.1.5 ! root      646:                op_illegal();
1.1       root      647:        } else {
                    648:                // BCHG.B #<imm>,<ea>
                    649:                CYCLE(6);
1.1.1.5 ! root      650:                uint bit = fetch_16() & 7;
        !           651:                uint32 ea = cea_data_8();
        !           652:                uint32 data = read_8(ea);
        !           653:                data = ACC.bchg(data, bit);
        !           654:                write_8(ea, data);
1.1       root      655:        }
                    656: }
                    657: 
                    658: // %0000_100010_000yyy BCLR.L #<imm>,Dy
                    659: // %0000_100010_mmmrrr BCLR.B #<imm>,<ea>
                    660: OP_DEF(bclr_imm_ea)
                    661: {
1.1.1.5 ! root      662:        uint n = ir & 0x3f;
1.1       root      663: 
                    664:        if (n < 8) {
                    665:                // BCLR.L #<imm>,Dy
                    666:                CYCLE(6);
1.1.1.5 ! root      667:                uint bit = fetch_16() & 31;
        !           668:                RegDY = ACC.bclr(RegDY, bit);
1.1       root      669:        } else if (n == 0x3c) {
                    670:                // BCLR.B #<imm>,<ea> の <ea> には #imm はない
1.1.1.5 ! root      671:                op_illegal();
1.1       root      672:        } else {
                    673:                // BCLR.B #<imm>,<ea>
                    674:                CYCLE(6);
1.1.1.5 ! root      675:                uint bit = fetch_16() & 7;
        !           676:                uint32 ea = cea_data_8();
        !           677:                uint32 data = read_8(ea);
        !           678:                data = ACC.bclr(data, bit);
        !           679:                write_8(ea, data);
1.1       root      680:        }
                    681: }
                    682: 
                    683: // %0000_100011_000yyy BSET.L #<imm>,Dy
                    684: // %0000_100011_mmmrrr BSET.B #<imm>,<ea>
                    685: OP_DEF(bset_imm_ea)
                    686: {
1.1.1.5 ! root      687:        uint n = ir & 0x3f;
1.1       root      688: 
                    689:        if (n < 8) {
                    690:                // BSET.L #<imm>,Dy
                    691:                CYCLE(6);
1.1.1.5 ! root      692:                uint bit = fetch_16() & 31;
        !           693:                RegDY = ACC.bset(RegDY, bit);
1.1       root      694:        } else if (n == 0x3c) {
                    695:                // BSET.B #<imm>,<ea> の <ea> には #imm はない
1.1.1.5 ! root      696:                op_illegal();
1.1       root      697:        } else {
                    698:                // BSET.B #<imm>,<ea>
                    699:                CYCLE(6);
1.1.1.5 ! root      700:                uint bit = fetch_16() & 7;
        !           701:                uint32 ea = cea_data_8();
        !           702:                uint32 data = read_8(ea);
        !           703:                data = ACC.bset(data, bit);
        !           704:                write_8(ea, data);
1.1       root      705:        }
                    706: }
                    707: 
                    708: // %0000_101000_mmmrrr EORI.B #<imm>,<ea>
                    709: // %0000_101000_111100 EORI.B #<imm>,CCR
                    710: OP_DEF(eori_b)
                    711: {
1.1.1.5 ! root      712:        uint n = ir & 0x3f;
1.1       root      713: 
1.1.1.5 ! root      714:        uint32 src = fetch_16() & 0xff;
1.1       root      715:        if (n < 8) {
                    716:                // EORI.B #<imm>,Dn
                    717:                CYCLE(2);
1.1.1.5 ! root      718:                uint32 dst = (reg.D[n] & 0xff) ^ src;
        !           719:                ACC.move_8(dst);
        !           720:                reg.D[n] = (reg.D[n] & 0xffffff00) | dst;
1.1       root      721:        } else if (n == 0b111100) {
                    722:                // EORI.B #<imm>,SR
                    723:                CYCLE2(12, 14);
                    724:                CCR.Set(CCR.Get() ^ src);
                    725:        } else {
                    726:                // EORI.B #<imm>,<ea>
                    727:                CYCLE2(3, 4);
1.1.1.5 ! root      728:                uint32 ea = cea_data_8();
        !           729:                uint32 dst = read_8(ea);
1.1       root      730:                dst ^= src;
1.1.1.5 ! root      731:                ACC.move_8(dst);
        !           732:                write_8(ea, dst);
1.1       root      733:        }
                    734: }
                    735: 
                    736: // %0000_101001_mmmrrr EORI.W #<imm>,<ea>
                    737: // %0000_101001_111100 EORI.W #<imm>,SR
                    738: OP_DEF(eori_w)
                    739: {
1.1.1.5 ! root      740:        uint n = ir & 0x3f;
1.1       root      741: 
                    742:        if (n < 8) {
                    743:                // EORI.W #<imm>,Dn
                    744:                CYCLE(2);
1.1.1.5 ! root      745:                uint32 src = fetch_16();
        !           746:                uint32 dst = (reg.D[n] & 0xffff) ^ src;
        !           747:                ACC.move_16(dst);
        !           748:                reg.D[n] = (reg.D[n] & 0xffff0000) | dst;
1.1       root      749:        } else if (n == 0b111100) {
                    750:                // EORI.W #<imm>,SR
                    751:                SUPERVISOR_OP;
                    752:                CYCLE2(12, 14);
1.1.1.5 ! root      753:                uint32 src = fetch_16();
        !           754:                SetSR(GetSR() ^ src);
1.1       root      755:        } else {
                    756:                // EORI.W #<imm>,<ea>
                    757:                CYCLE2(3, 4);
1.1.1.5 ! root      758:                uint32 src = fetch_16();
        !           759:                uint32 ea = cea_data_16();
        !           760:                uint32 dst = read_16(ea);
1.1       root      761:                dst ^= src;
1.1.1.5 ! root      762:                ACC.move_16(dst);
        !           763:                write_16(ea, dst);
1.1       root      764:        }
                    765: }
                    766: 
                    767: // %0000_101010_mmmrrr EORI.L #<imm>,<ea>
                    768: OP_DEF(eori_l)
                    769: {
1.1.1.5 ! root      770:        uint n = ir & 0x3f;
1.1       root      771: 
1.1.1.5 ! root      772:        uint32 src = fetch_32();
1.1       root      773:        if (n < 8) {
                    774:                // EORI.L #<imm>,Dn
                    775:                CYCLE(2);
1.1.1.5 ! root      776:                reg.D[n] ^= src;
        !           777:                ACC.move_32(reg.D[n]);
1.1       root      778:        } else {
                    779:                // EORI.L #<imm>,<ea>
                    780:                CYCLE2(3, 4);
1.1.1.5 ! root      781:                uint32 ea = cea_data_32();
        !           782:                uint32 dst = read_32(ea);
1.1       root      783:                dst ^= src;
1.1.1.5 ! root      784:                ACC.move_32(dst);
        !           785:                write_32(ea, dst);
1.1       root      786:        }
                    787: }
                    788: 
                    789: // %0000_101011_mmmrrr CAS.B Dc,Du,<ea>
                    790: OP_DEF(cas_b)
                    791: {
1.1.1.5 ! root      792:        ir2 = fetch_16();
        !           793:        uint c = ir2 & 7;
        !           794:        uint u = (ir2 >> 6) & 7;
        !           795:        uint32 dc = reg.D[c] & 0xff;
        !           796:        uint32 du = reg.D[u] & 0xff;
        !           797:        uint ea = cea_data_8();
        !           798:        uint32 dst = read_8(ea);
1.1       root      799: 
1.1.1.5 ! root      800:        ACC.cmp_8(dc, dst);
1.1       root      801:        if (CCR.IsZ()) {
                    802:                // 等しければ、Du -> dst
                    803:                CYCLE(13);
1.1.1.5 ! root      804:                write_8(ea, du);
1.1       root      805:        } else {
                    806:                // そうでなければ、dst -> Dc
                    807:                CYCLE(11);
1.1.1.5 ! root      808:                reg.D[c] = (reg.D[c] & 0xffffff00) | dst;
1.1       root      809:        }
                    810: }
                    811: 
                    812: // %0000_110000_mmmrrr CMPI.B #<imm>,<ea>
                    813: OP_DEF(cmpi_b)
                    814: {
1.1.1.5 ! root      815:        uint n = ir & 0x3f;
1.1       root      816: 
                    817:        // CMPI はデータアドレッシングだが #imm がないことに注意
                    818:        if (n == 0x3c) {
1.1.1.5 ! root      819:                op_illegal();
1.1       root      820:                return;
                    821:        }
                    822:        CYCLE(2);
1.1.1.5 ! root      823:        uint32 src = fetch_16() & 0xff;
        !           824:        uint32 dst = fea_data_8();
        !           825:        ACC.cmp_8(src, dst);
1.1       root      826: }
                    827: 
                    828: // %0000_110001_mmmrrr CMPI.W #<imm>,<ea>
                    829: OP_DEF(cmpi_w)
                    830: {
1.1.1.5 ! root      831:        uint n = ir & 0x3f;
1.1       root      832: 
                    833:        // CMPI はデータアドレッシングだが #imm がないことに注意
                    834:        if (n == 0x3c) {
1.1.1.5 ! root      835:                op_illegal();
1.1       root      836:                return;
                    837:        }
                    838:        CYCLE(2);
1.1.1.5 ! root      839:        uint32 src = fetch_16();
        !           840:        uint32 dst = fea_data_16();
        !           841:        ACC.cmp_16(src, dst);
1.1       root      842: }
                    843: 
                    844: // %0000_110010_mmmrrr CMPI.L #<imm>,<ea>
                    845: OP_DEF(cmpi_l)
                    846: {
1.1.1.5 ! root      847:        uint n = ir & 0x3f;
1.1       root      848: 
                    849:        // CMPI はデータアドレッシングだが #imm がないことに注意
                    850:        if (n == 0x3c) {
1.1.1.5 ! root      851:                op_illegal();
1.1       root      852:                return;
                    853:        }
                    854:        CYCLE(2);
1.1.1.5 ! root      855:        uint32 src = fetch_32();
        !           856:        uint32 dst = fea_data_32();
        !           857:        ACC.cmp_32(src, dst);
1.1       root      858: }
                    859: 
                    860: // %0000_110011_mmmrrr CAS.W Dc,Du,<ea>
                    861: // %0000_110011_111100 CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
                    862: OP_DEF(cas_w)
                    863: {
1.1.1.5 ! root      864:        uint n = ir & 0x3f;
1.1       root      865: 
                    866:        if (n == 0x3c) {
                    867:                // CAS2.W Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
1.1.1.5 ! root      868:                ir2 = fetch_16();
        !           869:                uint32 ir3 = fetch_16();
        !           870:                uint c1 = ir2 & 7;
        !           871:                uint u1 = (ir2 >> 6) & 7;
        !           872:                uint r1 = ir2 >> 12;
1.1       root      873:                uint c2 = ir3 & 7;
                    874:                uint u2 = (ir3 >> 6) & 7;
                    875:                uint r2 = ir3 >> 12;
1.1.1.5 ! root      876:                uint32 dc1 = reg.D[c1] & 0xffff;
        !           877:                uint32 du1 = reg.D[u1] & 0xffff;
        !           878:                uint32 ea1 = reg.R[r1];
        !           879:                uint32 dc2 = reg.D[c2] & 0xffff;
        !           880:                uint32 du2 = reg.D[u2] & 0xffff;
        !           881:                uint32 ea2 = reg.R[r2];
        !           882: 
        !           883:                uint32 dst1 = read_16(ea1);
        !           884:                uint32 dst2 = read_16(ea2);
        !           885:                ACC.cmp_16(dc1, dst1);
1.1       root      886:                if (CCR.IsZ()) {
1.1.1.5 ! root      887:                        ACC.cmp_16(dc2, dst2);
1.1       root      888:                        if (CCR.IsZ()) {
                    889:                                // 更新オペランド -> デスティネーション
                    890:                                CYCLE2(0, 2);   // これは成功時の追加分
1.1.1.5 ! root      891:                                write_16(ea1, du1);
        !           892:                                write_16(ea2, du2);
1.1       root      893:                        }
                    894:                }
                    895:                // デスティネーション -> 比較オペランド
                    896:                CYCLE(24);      // 本当はこれは最大値
1.1.1.5 ! root      897:                reg.D[c1] = (reg.D[c1] & 0xffff0000) | dst1;
        !           898:                reg.D[c2] = (reg.D[c2] & 0xffff0000) | dst2;
1.1       root      899:        } else {
                    900:                // CAS.W Dc,Du,<ea>
1.1.1.5 ! root      901:                ir2 = fetch_16();
        !           902:                uint c = ir2 & 7;
        !           903:                uint u = (ir2 >> 6) & 7;
        !           904:                uint32 dc = reg.D[c] & 0xffff;
        !           905:                uint32 du = reg.D[u] & 0xffff;
        !           906:                uint ea = cea_data_16();
        !           907:                uint32 dst = read_16(ea);
1.1       root      908: 
1.1.1.5 ! root      909:                ACC.cmp_16(dc, dst);
1.1       root      910:                if (CCR.IsZ()) {
                    911:                        // 等しければ、Du -> dst
                    912:                        CYCLE(13);
1.1.1.5 ! root      913:                        write_16(ea, du);
1.1       root      914:                } else {
                    915:                        // そうでなければ、dst -> Dc
                    916:                        CYCLE(11);
1.1.1.5 ! root      917:                        reg.D[c] = (reg.D[c] & 0xffff0000) | dst;
1.1       root      918:                }
                    919:        }
                    920: }
                    921: 
                    922: // %0000_111000_mmmrrr MOVES.B <ea>,Rn
                    923: // %0000_111000_mmmrrr MOVES.B Rn,<ea>
                    924: OP_DEF(moves_b)
                    925: {
                    926:        SUPERVISOR_OP;
                    927: 
1.1.1.5 ! root      928:        ir2 = fetch_16();
        !           929:        uint n = ir2 >> 12;
1.1       root      930:        uint ea;
                    931:        uint32 data;
                    932: 
1.1.1.5 ! root      933:        if ((ir & 0x3f) < 16) {
        !           934:                op_illegal();
1.1       root      935:                return;
                    936:        }
                    937: 
1.1.1.5 ! root      938:        ea = cea_data_8();
        !           939:        if ((ir2 & 0x0800) == 0) {
1.1       root      940:                // <ea>,Rn
                    941:                CYCLE(7);
1.1.1.5 ! root      942:                data = read_8_fc(ea);
1.1       root      943:                if (n < 8) {    // Dn
1.1.1.5 ! root      944:                        reg.D[n] = (reg.D[n] & 0xffffff00) | data;
1.1       root      945:                } else {                // An
1.1.1.5 ! root      946:                        reg.R[n] = (int32)(int8)data;
1.1       root      947:                }
                    948:        } else {
                    949:                // Rn,<ea>
                    950:                CYCLE2(5, 6);
1.1.1.5 ! root      951:                data = reg.R[n] & 0xff;
        !           952:                write_8_fc(ea, data);
1.1       root      953:        }
                    954: }
                    955: 
                    956: // %0000_111001_mmmrrr MOVES.W <ea>,Rn
                    957: // %0000_111001_mmmrrr MOVES.W Rn,<ea>
                    958: OP_DEF(moves_w)
                    959: {
                    960:        SUPERVISOR_OP;
                    961: 
1.1.1.5 ! root      962:        ir2 = fetch_16();
        !           963:        uint n = ir2 >> 12;
1.1       root      964:        uint ea;
                    965:        uint32 data;
                    966: 
1.1.1.5 ! root      967:        if ((ir & 0x3f) < 16) {
        !           968:                op_illegal();
1.1       root      969:                return;
                    970:        }
                    971: 
1.1.1.5 ! root      972:        ea = cea_data_16();
        !           973:        if ((ir2 & 0x0800) == 0) {
1.1       root      974:                // <ea>,Rn
                    975:                CYCLE(7);
1.1.1.5 ! root      976:                data = read_16_fc(ea);
1.1       root      977:                if (n < 8) {    // Dn
1.1.1.5 ! root      978:                        reg.D[n] = (reg.D[n] & 0xffff0000) | data;
1.1       root      979:                } else {                // An
1.1.1.5 ! root      980:                        reg.R[n] = (int32)(int16)data;
1.1       root      981:                }
                    982:        } else {
                    983:                // Rn,<ea>
                    984:                CYCLE2(5, 6);
1.1.1.5 ! root      985:                data = reg.R[n] & 0xffff;
        !           986:                write_16_fc(ea, data);
1.1       root      987:        }
                    988: }
                    989: 
                    990: // %0000_111010_mmmrrr MOVES.L <ea>,Rn
                    991: // %0000_111010_mmmrrr MOVES.L Rn,<ea>
                    992: OP_DEF(moves_l)
                    993: {
                    994:        SUPERVISOR_OP;
                    995: 
1.1.1.5 ! root      996:        ir2 = fetch_16();
        !           997:        uint n = ir2 >> 12;
1.1       root      998:        uint ea;
                    999:        uint32 data;
                   1000: 
1.1.1.5 ! root     1001:        if ((ir & 0x3f) < 16) {
        !          1002:                op_illegal();
1.1       root     1003:                return;
                   1004:        }
                   1005: 
1.1.1.5 ! root     1006:        ea = cea_data_32();
        !          1007:        if ((ir2 & 0x0800) == 0) {
1.1       root     1008:                // <ea>,Rn
                   1009:                CYCLE(7);
1.1.1.5 ! root     1010:                data = read_32_fc(ea);
        !          1011:                reg.R[n] = data;
1.1       root     1012:        } else {
                   1013:                // Rn,<ea>
                   1014:                CYCLE2(5, 6);
1.1.1.5 ! root     1015:                data = reg.R[n];
        !          1016:                write_32_fc(ea, data);
1.1       root     1017:        }
                   1018: }
                   1019: 
                   1020: // %0000_111011_mmmrrr CAS.L Dc,Du,<ea>
                   1021: // %0000_111011_111100 CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
                   1022: OP_DEF(cas_l)
                   1023: {
1.1.1.5 ! root     1024:        uint n = ir & 0x3f;
1.1       root     1025: 
                   1026:        if (n == 0x3c) {
                   1027:                // CAS2.L Dc1:Dc2,Du1:Du2,(Rn1):(Rn2)
1.1.1.5 ! root     1028:                ir2 = fetch_16();
        !          1029:                uint32 ir3 = fetch_16();
        !          1030:                uint c1 = ir2 & 7;
        !          1031:                uint u1 = (ir2 >> 6) & 7;
        !          1032:                uint r1 = ir2 >> 12;
1.1       root     1033:                uint c2 = ir3 & 7;
                   1034:                uint u2 = (ir3 >> 6) & 7;
                   1035:                uint r2 = ir3 >> 12;
1.1.1.5 ! root     1036:                uint32 dc1 = reg.D[c1];
        !          1037:                uint32 du1 = reg.D[u1];
        !          1038:                uint32 ea1 = reg.R[r1];
        !          1039:                uint32 dc2 = reg.D[c2];
        !          1040:                uint32 du2 = reg.D[u2];
        !          1041:                uint32 ea2 = reg.R[r2];
        !          1042: 
        !          1043:                uint32 dst1 = read_32(ea1);
        !          1044:                uint32 dst2 = read_32(ea2);
        !          1045:                ACC.cmp_32(dc1, dst1);
1.1       root     1046:                if (CCR.IsZ()) {
1.1.1.5 ! root     1047:                        ACC.cmp_32(dc2, dst2);
1.1       root     1048:                        if (CCR.IsZ()) {
                   1049:                                // 更新オペランド -> デスティネーション
                   1050:                                CYCLE2(0, 2);   // これは成功時の追加分
1.1.1.5 ! root     1051:                                write_32(ea1, du1);
        !          1052:                                write_32(ea2, du2);
1.1       root     1053:                        }
                   1054:                }
                   1055:                // デスティネーション -> 比較オペランド
                   1056:                CYCLE(24);      // 本当はこれは最大値
1.1.1.5 ! root     1057:                reg.D[c1] = dst1;
        !          1058:                reg.D[c2] = dst2;
1.1       root     1059:        } else {
                   1060:                // CAS.L Dc,Du,<ea>
1.1.1.5 ! root     1061:                ir2 = fetch_16();
        !          1062:                uint c = ir2 & 7;
        !          1063:                uint u = (ir2 >> 6) & 7;
        !          1064:                uint32 dc = reg.D[c];
        !          1065:                uint32 du = reg.D[u];
        !          1066:                uint ea = cea_data_32();
        !          1067:                uint32 dst = read_32(ea);
1.1       root     1068: 
1.1.1.5 ! root     1069:                ACC.cmp_32(dc, dst);
1.1       root     1070:                if (CCR.IsZ()) {
                   1071:                        // 等しければ、Du -> dst
                   1072:                        CYCLE(13);
1.1.1.5 ! root     1073:                        write_32(ea, du);
1.1       root     1074:                } else {
                   1075:                        // そうでなければ、dst -> Dc
                   1076:                        CYCLE(11);
1.1.1.5 ! root     1077:                        reg.D[c] = dst;
1.1       root     1078:                }
                   1079:        }
                   1080: }
                   1081: 
                   1082: // %0001_xxx000_mmmrrr MOVE.B <ea>,Dx
                   1083: OP_DEF(move_b_ea_dn)
                   1084: {
                   1085:        CYCLE(2);
1.1.1.5 ! root     1086:        uint32 data = fea_all_8();
        !          1087:        ACC.move_8(data);
1.1       root     1088:        RegDX = (RegDX & 0xffffff00) | data;
                   1089: }
                   1090: 
                   1091: // %0001_xxx010_mmmrrr MOVE.B <ea>,(Ax)
                   1092: OP_DEF(move_b_ea_anin)
                   1093: {
                   1094:        // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5)
                   1095:        CYCLE2(4, 5);
1.1.1.5 ! root     1096:        uint32 data = fea_all_8();
        !          1097:        uint32 ea = cea_anin(RegIRX);
        !          1098:        ACC.move_8(data);
        !          1099:        write_8(ea, data);
1.1       root     1100: }
                   1101: 
                   1102: // %0001_xxx011_mmmrrr MOVE.B <ea>,(Ax)+
                   1103: OP_DEF(move_b_ea_anpi)
                   1104: {
                   1105:        // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5)
                   1106:        CYCLE2(4, 5);
1.1.1.5 ! root     1107:        uint32 data = fea_all_8();
        !          1108:        uint32 ea = cea_anpi_8(RegIRX);
        !          1109:        ACC.move_8(data);
        !          1110:        write_8(ea, data);
1.1       root     1111: }
                   1112: 
                   1113: // %0001_xxx100_mmmrrr MOVE.B <ea>,-(Ax)
                   1114: OP_DEF(move_b_ea_anpd)
                   1115: {
                   1116:        // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5)
                   1117:        CYCLE2(4, 5);
1.1.1.5 ! root     1118:        uint32 data = fea_all_8();
        !          1119:        uint32 ea = cea_anpd_8(RegIRX);
        !          1120:        ACC.move_8(data);
        !          1121:        write_8(ea, data);
1.1       root     1122: }
                   1123: 
                   1124: // %0001_xxx101_mmmrrr MOVE.B <ea>,d16(Ax)
                   1125: OP_DEF(move_b_ea_andi)
                   1126: {
                   1127:        CYCLE2(4, 5);
1.1.1.5 ! root     1128:        uint32 data = fea_all_8();
        !          1129:        uint32 ea = cea_andi(RegIRX);
        !          1130:        ACC.move_8(data);
        !          1131:        write_8(ea, data);
1.1       root     1132: }
                   1133: 
                   1134: // %0001_xxx110_mmmrrr MOVE.B <ea>,(Ax,IX)
                   1135: OP_DEF(move_b_ea_anix)
                   1136: {
                   1137:        // XXX 実際にはdstのフォーマットによって(8,9)-(20,23)
                   1138:        CYCLE2(16, 18);
1.1.1.5 ! root     1139:        uint32 data = fea_all_8();
        !          1140:        uint32 ea = cea_anix(RegIRX);
        !          1141:        ACC.move_8(data);
        !          1142:        write_8(ea, data);
1.1       root     1143: }
                   1144: 
                   1145: // %0001_000111_mmmrrr MOVE.B <ea>,Abs.W
                   1146: OP_DEF(move_b_ea_absw)
                   1147: {
                   1148:        CYCLE2(4, 5);
1.1.1.5 ! root     1149:        uint32 data = fea_all_8();
        !          1150:        uint32 ea = cea_absw();
        !          1151:        ACC.move_8(data);
        !          1152:        write_8(ea, data);
1.1       root     1153: }
                   1154: 
                   1155: // %0001_001111_mmmrrr MOVE.B <ea>,Abs.L
                   1156: OP_DEF(move_b_ea_absl)
                   1157: {
                   1158:        CYCLE2(6, 7);
1.1.1.5 ! root     1159:        uint32 data = fea_all_8();
        !          1160:        uint32 ea = cea_absl();
        !          1161:        ACC.move_8(data);
        !          1162:        write_8(ea, data);
1.1       root     1163: }
                   1164: 
                   1165: // %0010_xxx000_mmmrrr MOVE.L <ea>,Dx
                   1166: OP_DEF(move_l_ea_dn)
                   1167: {
                   1168:        CYCLE(2);
1.1.1.5 ! root     1169:        uint32 data = fea_all_32();
        !          1170:        ACC.move_32(data);
1.1       root     1171:        RegDX = data;
                   1172: }
                   1173: 
                   1174: // %0010_xxx001_mmmrrr MOVEA.L <ea>,Ax
                   1175: OP_DEF(movea_l)
                   1176: {
                   1177:        CYCLE(2);
1.1.1.5 ! root     1178:        uint32 data = fea_all_32();
1.1       root     1179:        RegAX = data;
                   1180: }
                   1181: 
                   1182: // %0010_xxx010_mmmrrr MOVE.L <ea>,(Ax)
                   1183: OP_DEF(move_l_ea_anin)
                   1184: {
                   1185:        // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5)
                   1186:        CYCLE2(4, 5);
1.1.1.5 ! root     1187:        uint32 data = fea_all_32();
        !          1188:        uint32 ea = cea_anin(RegIRX);
        !          1189:        ACC.move_32(data);
        !          1190:        write_32(ea, data);
1.1       root     1191: }
                   1192: 
                   1193: // %0010_xxx011_mmmrrr MOVE.L <ea>,(Ax)+
                   1194: OP_DEF(move_l_ea_anpi)
                   1195: {
                   1196:        // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5)
                   1197:        CYCLE2(4, 5);
1.1.1.5 ! root     1198:        uint32 data = fea_all_32();
        !          1199:        uint32 ea = cea_anpi_32(RegIRX);
        !          1200:        ACC.move_32(data);
        !          1201:        write_32(ea, data);
1.1       root     1202: }
                   1203: 
                   1204: // %0010_xxx100_mmmrrr MOVE.L <ea>,-(Ax)
                   1205: OP_DEF(move_l_ea_anpd)
                   1206: {
                   1207:        // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5)
                   1208:        CYCLE2(4, 5);
1.1.1.5 ! root     1209:        uint32 data = fea_all_32();
        !          1210:        uint32 ea = cea_anpd_32(RegIRX);
        !          1211:        ACC.move_32(data);
        !          1212:        write_32(ea, data);
1.1       root     1213: }
                   1214: 
                   1215: // %0010_xxx101_mmmrrr MOVE.L <ea>,d16(Ax)
                   1216: OP_DEF(move_l_ea_andi)
                   1217: {
                   1218:        CYCLE2(4, 5);
1.1.1.5 ! root     1219:        uint32 data = fea_all_32();
        !          1220:        uint32 ea = cea_andi(RegIRX);
        !          1221:        ACC.move_32(data);
        !          1222:        write_32(ea, data);
1.1       root     1223: }
                   1224: 
                   1225: // %0010_xxx110_mmmrrr MOVE.L <ea>,(Ax,IX)
                   1226: OP_DEF(move_l_ea_anix)
                   1227: {
                   1228:        // XXX 実際にはdstのフォーマットによって(8,9)-(20,23)
                   1229:        CYCLE2(16, 18);
1.1.1.5 ! root     1230:        uint32 data = fea_all_32();
        !          1231:        uint32 ea = cea_anix(RegIRX);
        !          1232:        ACC.move_32(data);
        !          1233:        write_32(ea, data);
1.1       root     1234: }
                   1235: 
                   1236: // %0010_000111_mmmrrr MOVE.L <ea>,Abs.W
                   1237: OP_DEF(move_l_ea_absw)
                   1238: {
                   1239:        CYCLE2(4, 5);
1.1.1.5 ! root     1240:        uint32 data = fea_all_32();
        !          1241:        uint32 ea = cea_absw();
        !          1242:        ACC.move_32(data);
        !          1243:        write_32(ea, data);
1.1       root     1244: }
                   1245: 
                   1246: // %0010_001111_mmmrrr MOVE.L <ea>,Abs.L
                   1247: OP_DEF(move_l_ea_absl)
                   1248: {
                   1249:        CYCLE2(6, 7);
1.1.1.5 ! root     1250:        uint32 data = fea_all_32();
        !          1251:        uint32 ea = cea_absl();
        !          1252:        ACC.move_32(data);
        !          1253:        write_32(ea, data);
1.1       root     1254: }
                   1255: 
                   1256: // %0011_xxx000_mmmrrr MOVE.W <ea>,Dx
                   1257: OP_DEF(move_w_ea_dn)
                   1258: {
                   1259:        CYCLE(2);
1.1.1.5 ! root     1260:        uint32 data = fea_all_16();
        !          1261:        ACC.move_16(data);
1.1       root     1262:        RegDX = (RegDX & 0xffff0000) | data;
                   1263: }
                   1264: 
                   1265: // %0011_xxx001_mmmrrr MOVEA.W <ea>,Ax
                   1266: OP_DEF(movea_w)
                   1267: {
                   1268:        CYCLE(2);
1.1.1.5 ! root     1269:        uint32 data = (int32)(int16)fea_all_16();
1.1       root     1270:        RegAX = data;
                   1271: }
                   1272: 
                   1273: // %0011_xxx010_mmmrrr MOVE.W <ea>,(Ax)
                   1274: OP_DEF(move_w_ea_anin)
                   1275: {
                   1276:        // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5)
                   1277:        CYCLE2(4, 5);
1.1.1.5 ! root     1278:        uint32 data = fea_all_16();
        !          1279:        uint32 ea = cea_anin(RegIRX);
        !          1280:        ACC.move_16(data);
        !          1281:        write_16(ea, data);
1.1       root     1282: }
                   1283: 
                   1284: // %0011_xxx011_mmmrrr MOVE.W <ea>,(Ax)+
                   1285: OP_DEF(move_w_ea_anpi)
                   1286: {
                   1287:        // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5)
                   1288:        CYCLE2(4, 5);
1.1.1.5 ! root     1289:        uint32 data = fea_all_16();
        !          1290:        uint32 ea = cea_anpi_16(RegIRX);
        !          1291:        ACC.move_16(data);
        !          1292:        write_16(ea, data);
1.1       root     1293: }
                   1294: 
                   1295: // %0011_xxx100_mmmrrr MOVE.W <ea>,-(Ax)
                   1296: OP_DEF(move_w_ea_anpd)
                   1297: {
                   1298:        // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5)
                   1299:        CYCLE2(4, 5);
1.1.1.5 ! root     1300:        uint32 data = fea_all_16();
        !          1301:        uint32 ea = cea_anpd_16(RegIRX);
        !          1302:        ACC.move_16(data);
        !          1303:        write_16(ea, data);
1.1       root     1304: }
                   1305: 
                   1306: // %0011_xxx101_mmmrrr MOVE.W <ea>,d16(Ax)
                   1307: OP_DEF(move_w_ea_andi)
                   1308: {
                   1309:        CYCLE2(4, 5);
1.1.1.5 ! root     1310:        uint32 data = fea_all_16();
        !          1311:        uint32 ea = cea_andi(RegIRX);
        !          1312:        ACC.move_16(data);
        !          1313:        write_16(ea, data);
1.1       root     1314: }
                   1315: 
                   1316: // %0011_xxx110_mmmrrr MOVE.W <ea>,(Ax,IX)
                   1317: OP_DEF(move_w_ea_anix)
                   1318: {
                   1319:        // XXX 実際にはdstのフォーマットによって(8,9)-(20,23)
                   1320:        CYCLE2(16, 18);
1.1.1.5 ! root     1321:        uint32 data = fea_all_16();
        !          1322:        uint32 ea = cea_anix(RegIRX);
        !          1323:        ACC.move_16(data);
        !          1324:        write_16(ea, data);
1.1       root     1325: }
                   1326: 
                   1327: // %0011_000111_mmmrrr MOVE.W <ea>,Abs.W
                   1328: OP_DEF(move_w_ea_absw)
                   1329: {
                   1330:        CYCLE2(4, 5);
1.1.1.5 ! root     1331:        uint32 data = fea_all_16();
        !          1332:        uint32 ea = cea_absw();
        !          1333:        ACC.move_16(data);
        !          1334:        write_16(ea, data);
1.1       root     1335: }
                   1336: 
                   1337: // %0011_001111_mmmrrr MOVE.W <ea>,Abs.L
                   1338: OP_DEF(move_w_ea_absl)
                   1339: {
                   1340:        CYCLE2(6, 7);
1.1.1.5 ! root     1341:        uint32 data = fea_all_16();
        !          1342:        uint32 ea = cea_absl();
        !          1343:        ACC.move_16(data);
        !          1344:        write_16(ea, data);
1.1       root     1345: }
                   1346: 
                   1347: // %0100_000000_mmmrrr NEGX.B <ea>
                   1348: OP_DEF(negx_b)
                   1349: {
1.1.1.5 ! root     1350:        uint n = ir & 0x3f;
1.1       root     1351: 
                   1352:        if (n < 8) {
                   1353:                // NEGX.B Dn
                   1354:                CYCLE(2);
1.1.1.5 ! root     1355:                uint32 data = reg.D[n] & 0xff;
        !          1356:                data = ACC.subx_8(data, 0);
        !          1357:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
1.1       root     1358:        } else if (n < 16) {
1.1.1.5 ! root     1359:                op_illegal();
1.1       root     1360:        } else {
                   1361:                // NEGX.B <ea>
                   1362:                CYCLE2(3, 4);
1.1.1.5 ! root     1363:                uint32 ea = cea_data_8();
        !          1364:                uint32 data = read_8(ea);
        !          1365:                data = ACC.subx_8(data, 0);
        !          1366:                write_8(ea, data);
1.1       root     1367:        }
                   1368: }
                   1369: 
                   1370: // %0100_000001_mmmrrr NEGX.W <ea>
                   1371: OP_DEF(negx_w)
                   1372: {
1.1.1.5 ! root     1373:        uint n = ir & 0x3f;
1.1       root     1374: 
                   1375:        if (n < 8) {
                   1376:                // NEGX.W Dn
                   1377:                CYCLE(2);
1.1.1.5 ! root     1378:                uint32 data = reg.D[n] & 0xffff;
        !          1379:                data = ACC.subx_16(data, 0);
        !          1380:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
1.1       root     1381:        } else if (n < 16) {
1.1.1.5 ! root     1382:                op_illegal();
1.1       root     1383:        } else {
                   1384:                // NEGX.W <ea>
                   1385:                CYCLE2(3, 4);
1.1.1.5 ! root     1386:                uint32 ea = cea_data_16();
        !          1387:                uint32 data = read_16(ea);
        !          1388:                data = ACC.subx_16(data, 0);
        !          1389:                write_16(ea, data);
1.1       root     1390:        }
                   1391: }
                   1392: 
                   1393: // %0100_000010_mmmrrr NEGX.L <ea>
                   1394: OP_DEF(negx_l)
                   1395: {
1.1.1.5 ! root     1396:        uint n = ir & 0x3f;
1.1       root     1397: 
                   1398:        if (n < 8) {
                   1399:                // NEGX.L Dn
                   1400:                CYCLE(2);
1.1.1.5 ! root     1401:                reg.D[n] = ACC.subx_32(reg.D[n], 0);
1.1       root     1402:        } else if (n < 16) {
1.1.1.5 ! root     1403:                op_illegal();
1.1       root     1404:        } else {
                   1405:                // NEGX.L <ea>
                   1406:                CYCLE2(3, 4);
1.1.1.5 ! root     1407:                uint32 ea = cea_data_32();
        !          1408:                uint32 data = read_32(ea);
        !          1409:                data = ACC.subx_32(data, 0);
        !          1410:                write_32(ea, data);
1.1       root     1411:        }
                   1412: }
                   1413: 
                   1414: // %0100_000011_mmmrrr MOVE.W SR,<ea>
                   1415: OP_DEF(move_sr_ea)
                   1416: {
                   1417:        SUPERVISOR_OP;
                   1418: 
1.1.1.5 ! root     1419:        uint n = ir & 0x3f;
1.1       root     1420:        if (n < 8) {
                   1421:                // MOVE.W SR,Dn
                   1422:                CYCLE(4);
1.1.1.5 ! root     1423:                reg.D[n] = (reg.D[n] & 0xffff0000) | GetSR();
1.1       root     1424:        } else {
                   1425:                // MOVE.W SR,<ea>
                   1426:                CYCLE2(4, 5);
1.1.1.5 ! root     1427:                uint32 ea = cea_data_16();
        !          1428:                write_16(ea, GetSR());
1.1       root     1429:        }
                   1430: }
                   1431: 
                   1432: // %0100_xxx100_mmmrrr CHK.L <ea>,Dx
                   1433: OP_DEF(chk_l)
                   1434: {
                   1435:        uint32 dst = RegDX;
1.1.1.5 ! root     1436:        ACC.move_32(dst);
1.1       root     1437:        if (CCR.IsN()) {
                   1438:                // これは最大値で次の条件式が成立した時の値なので、
                   1439:                // 実際にはこれより小さい確定した値のはずだけど。
                   1440:                CYCLE2(28, 30);
1.1.1.5 ! root     1441:                Exception(M68K::EXCEP_CHK);
1.1       root     1442:                return;
                   1443:        }
                   1444:        // 本当はこうじゃないけど、とりあえず
1.1.1.5 ! root     1445:        uint32 src = fea_data_32();
1.1       root     1446:        if ((int32)dst > (int32)src) {
                   1447:                CYCLE2(28, 30);
1.1.1.5 ! root     1448:                CCR.SetN(false);
        !          1449:                Exception(M68K::EXCEP_CHK);
1.1       root     1450:                return;
                   1451:        }
                   1452:        CYCLE(8);
                   1453: }
                   1454: 
                   1455: // %0100_xxx110_mmmrrr CHK.W <ea>,Dx
                   1456: OP_DEF(chk_w)
                   1457: {
                   1458:        uint32 dst = RegDX & 0xffff;
1.1.1.5 ! root     1459:        ACC.move_16(dst);
1.1       root     1460:        if (CCR.IsN()) {
                   1461:                // これは最大値で次の条件式が成立した時の値なので、
                   1462:                // 実際にはこれより小さい確定した値のはずだけど。
                   1463:                CYCLE2(28, 30);
1.1.1.5 ! root     1464:                Exception(M68K::EXCEP_CHK);
1.1       root     1465:                return;
                   1466:        }
                   1467:        // 本当はこうじゃないけど、とりあえず
1.1.1.5 ! root     1468:        uint32 src = fea_data_16();
1.1       root     1469:        if ((int16)dst > (int16)src) {
                   1470:                CYCLE2(28, 30);
1.1.1.5 ! root     1471:                CCR.SetN(false);
        !          1472:                Exception(M68K::EXCEP_CHK);
1.1       root     1473:                return;
                   1474:        }
                   1475:        CYCLE(8);
                   1476: }
                   1477: 
                   1478: // %0100_xxx111_mmmrrr LEA.L <ea>,Ax
                   1479: // %0100_100111_000yyy EXTB.L Dy
                   1480: OP_DEF(lea)
                   1481: {
1.1.1.5 ! root     1482:        uint n = ir & 0x3f;
1.1       root     1483: 
                   1484:        if (n < 8) {
                   1485:                // EXTB.L Dy
                   1486:                CYCLE(4);
                   1487:                RegDY = (int32)(int8)(RegDY & 0xff);
1.1.1.5 ! root     1488:                ACC.move_32(RegDY);
1.1       root     1489:        } else {
                   1490:                // LEA.L <ea>,Ax
                   1491:                CYCLE(2);
1.1.1.5 ! root     1492:                RegAX = cea_ctrl();
1.1       root     1493:        }
                   1494: }
                   1495: 
                   1496: // %0100_001000_mmmrrr CLR.B <ea>
                   1497: OP_DEF(clr_b)
                   1498: {
1.1.1.5 ! root     1499:        uint n = ir & 0x3f;
1.1       root     1500: 
                   1501:        if (n < 8) {
                   1502:                // CLR.B Dn
                   1503:                CYCLE(2);
                   1504:                RegDY &= 0xffffff00;
1.1.1.5 ! root     1505:                ACC.move_8(0);
1.1       root     1506:        } else {
                   1507:                // CLR.B <ea>
                   1508:                CYCLE2(3, 4);
1.1.1.5 ! root     1509:                uint32 ea = cea_data_8();
        !          1510:                ACC.move_8(0);
        !          1511:                write_8(ea, 0);
1.1       root     1512:        }
                   1513: }
                   1514: 
                   1515: // %0100_001001_mmmrrr CLR.W <ea>
                   1516: OP_DEF(clr_w)
                   1517: {
1.1.1.5 ! root     1518:        uint n = ir & 0x3f;
1.1       root     1519: 
                   1520:        if (n < 8) {
                   1521:                // CLR.W Dn
                   1522:                CYCLE(2);
                   1523:                RegDY &= 0xffff0000;
1.1.1.5 ! root     1524:                ACC.move_16(0);
1.1       root     1525:        } else {
                   1526:                // CLR.W <ea>
                   1527:                CYCLE2(3, 4);
1.1.1.5 ! root     1528:                uint32 ea = cea_data_16();
        !          1529:                ACC.move_16(0);
        !          1530:                write_16(ea, 0);
1.1       root     1531:        }
                   1532: }
                   1533: 
                   1534: // %0100_001010_mmmrrr CLR.L <ea>
                   1535: OP_DEF(clr_l)
                   1536: {
1.1.1.5 ! root     1537:        uint n = ir & 0x3f;
1.1       root     1538: 
                   1539:        if (n < 8) {
                   1540:                // CLR.L Dn
                   1541:                CYCLE(2);
                   1542:                RegDY = 0;
1.1.1.5 ! root     1543:                ACC.move_32(0);
1.1       root     1544:        } else {
                   1545:                // CLR.L <ea>
                   1546:                CYCLE2(3, 4);
1.1.1.5 ! root     1547:                uint32 ea = cea_data_32();
        !          1548:                ACC.move_32(0);
        !          1549:                write_32(ea, 0);
1.1       root     1550:        }
                   1551: }
                   1552: 
                   1553: // %0100_001011_mmmrrr MOVE.W CCR,<ea>
                   1554: OP_DEF(move_ccr_ea)
                   1555: {
1.1.1.5 ! root     1556:        uint n = ir & 0x3f;
1.1       root     1557: 
                   1558:        // 転送は16ビットで行われ、上位バイトと未実装ビットは %0 になる。
                   1559:        if (n < 8) {
                   1560:                // MOVE.W CCR,Dn
                   1561:                CYCLE(4);
1.1.1.5 ! root     1562:                reg.D[n] = (reg.D[n] & 0xffff0000) | CCR.Get();
1.1       root     1563:        } else if (n < 16) {
                   1564:                // MOVE.W CCR,An はない
1.1.1.5 ! root     1565:                op_illegal();
1.1       root     1566:        } else {
                   1567:                // MOVE.W CCR,<ea>
                   1568:                CYCLE2(4, 5);
1.1.1.5 ! root     1569:                uint32 ea = cea_data_16();
        !          1570:                write_16(ea, CCR.Get());
1.1       root     1571:        }
                   1572: }
                   1573: 
                   1574: // %0100_010000_mmmrrr NEG.B <ea>
                   1575: OP_DEF(neg_b)
                   1576: {
1.1.1.5 ! root     1577:        uint n = ir & 0x3f;
1.1       root     1578: 
                   1579:        if (n < 8) {
                   1580:                // NEG.B Dn
                   1581:                CYCLE(2);
1.1.1.5 ! root     1582:                uint32 data = ACC.sub_8(reg.D[n] & 0xff, 0);
        !          1583:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
1.1       root     1584:        } else {
                   1585:                // NEG.B <ea>
                   1586:                CYCLE2(3, 4);
1.1.1.5 ! root     1587:                uint32 ea = cea_data_8();
        !          1588:                uint32 data = read_8(ea);
        !          1589:                data = ACC.sub_8(data, 0);
        !          1590:                write_8(ea, data);
1.1       root     1591:        }
                   1592: }
                   1593: 
                   1594: // %0100_010001_mmmrrr NEG.W <ea>
                   1595: OP_DEF(neg_w)
                   1596: {
1.1.1.5 ! root     1597:        uint n = ir & 0x3f;
1.1       root     1598: 
                   1599:        if (n < 8) {
                   1600:                // NEG.W Dn
                   1601:                CYCLE(2);
1.1.1.5 ! root     1602:                uint32 data = ACC.sub_16(reg.D[n] & 0xffff, 0);
        !          1603:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
1.1       root     1604:        } else {
                   1605:                // NEG.W <ea>
                   1606:                CYCLE2(3, 4);
1.1.1.5 ! root     1607:                uint32 ea = cea_data_16();
        !          1608:                uint32 data = read_16(ea);
        !          1609:                data = ACC.sub_16(data, 0);
        !          1610:                write_16(ea, data);
1.1       root     1611:        }
                   1612: }
                   1613: 
                   1614: // %0100_010010_mmmrrr NEG.L <ea>
                   1615: OP_DEF(neg_l)
                   1616: {
1.1.1.5 ! root     1617:        uint n = ir & 0x3f;
1.1       root     1618: 
                   1619:        if (n < 8) {
                   1620:                // NEG.L Dn
                   1621:                CYCLE(2);
1.1.1.5 ! root     1622:                reg.D[n] = ACC.sub_32(reg.D[n], 0);
1.1       root     1623:        } else {
                   1624:                // NEG.L <ea>
                   1625:                CYCLE2(3, 4);
1.1.1.5 ! root     1626:                uint32 ea = cea_data_32();
        !          1627:                uint32 data = read_32(ea);
        !          1628:                data = ACC.sub_32(data, 0);
        !          1629:                write_32(ea, data);
1.1       root     1630:        }
                   1631: }
                   1632: 
                   1633: // %0100_010011_mmmrrr MOVE.W <ea>,CCR
                   1634: OP_DEF(move_ea_ccr)
                   1635: {
1.1.1.5 ! root     1636:        uint n = ir & 0x3f;
1.1       root     1637: 
                   1638:        if (n < 8) {
                   1639:                // MOVE.W Dn,CCR
                   1640:                CYCLE(4);
1.1.1.5 ! root     1641:                uint32 data = reg.D[n] & 0xff;
1.1       root     1642:                CCR.Set(data);
                   1643:        } else if (n < 16) {
                   1644:                // MOVE.W An,CCR はない
1.1.1.5 ! root     1645:                op_illegal();
1.1       root     1646:        } else {
                   1647:                // MOVE.W <ea>,CCR
                   1648:                CYCLE(4);
1.1.1.5 ! root     1649:                uint32 data = fea_data_16();
1.1       root     1650:                CCR.Set(data);
                   1651:        }
                   1652: }
                   1653: 
                   1654: // %0100_011000_mmmrrr NOT.B <ea>
                   1655: OP_DEF(not_b)
                   1656: {
1.1.1.5 ! root     1657:        uint n = ir & 0x3f;
1.1       root     1658: 
                   1659:        if (n < 8) {
                   1660:                // NOT.B Dn
                   1661:                CYCLE(2);
1.1.1.5 ! root     1662:                uint32 data = (~reg.D[n]) & 0xff;
        !          1663:                ACC.move_8(data);
        !          1664:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
1.1       root     1665:        } else {
                   1666:                // NOT.B <ea>
                   1667:                CYCLE2(3, 4);
1.1.1.5 ! root     1668:                uint32 ea = cea_data_8();
        !          1669:                uint32 data = read_8(ea);
1.1       root     1670:                data = (~data) & 0xff;
1.1.1.5 ! root     1671:                ACC.move_8(data);
        !          1672:                write_8(ea, data);
1.1       root     1673:        }
                   1674: }
                   1675: 
                   1676: // %0100_011001_mmmrrr NOT.W <ea>
                   1677: OP_DEF(not_w)
                   1678: {
1.1.1.5 ! root     1679:        uint n = ir & 0x3f;
1.1       root     1680: 
                   1681:        if (n < 8) {
                   1682:                // NOT.W Dn
                   1683:                CYCLE(2);
1.1.1.5 ! root     1684:                uint32 data = (~reg.D[n]) & 0xffff;
        !          1685:                ACC.move_16(data);
        !          1686:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
1.1       root     1687:        } else {
                   1688:                // NOT.W <ea>
                   1689:                CYCLE2(3, 4);
1.1.1.5 ! root     1690:                uint32 ea = cea_data_16();
        !          1691:                uint32 data = read_16(ea);
1.1       root     1692:                data = (~data) & 0xffff;
1.1.1.5 ! root     1693:                ACC.move_16(data);
        !          1694:                write_16(ea, data);
1.1       root     1695:        }
                   1696: }
                   1697: 
                   1698: // %0100_011010_mmmrrr NOT.L <ea>
                   1699: OP_DEF(not_l)
                   1700: {
1.1.1.5 ! root     1701:        uint n = ir & 0x3f;
1.1       root     1702: 
                   1703:        if (n < 8) {
                   1704:                // NOT.L Dn
                   1705:                CYCLE(2);
1.1.1.5 ! root     1706:                reg.D[n] = ~reg.D[n];
        !          1707:                ACC.move_32(reg.D[n]);
1.1       root     1708:        } else {
                   1709:                // NOT.L <ea>
                   1710:                CYCLE2(3, 4);
1.1.1.5 ! root     1711:                uint32 ea = cea_data_32();
        !          1712:                uint32 data = read_32(ea);
1.1       root     1713:                data = ~data;
1.1.1.5 ! root     1714:                ACC.move_32(data);
        !          1715:                write_32(ea, data);
1.1       root     1716:        }
                   1717: }
                   1718: 
                   1719: // %0100_011011_mmmrrr MOVE.W <ea>,SR
                   1720: OP_DEF(move_ea_sr)
                   1721: {
                   1722:        CYCLE2(8, 10);
1.1.1.5 ! root     1723:        uint16 data = fea_data_16();
        !          1724:        SetSR(data);
1.1       root     1725: }
                   1726: 
                   1727: // %0100_100000_mmmrrr NBCD.B <ea>
                   1728: // %0100_100000_001yyy LINK.L Ay,#<imm>
                   1729: OP_DEF(nbcd)
                   1730: {
1.1.1.5 ! root     1731:        uint n = ir & 0x3f;
1.1       root     1732:        int32 imm;
                   1733: 
                   1734:        if (n < 8) {
                   1735:                // NBCD.B Dn
                   1736:                CYCLE(6);
                   1737:                uint32 dst = RegDY & 0xff;
1.1.1.5 ! root     1738:                dst = ACC.sbcd_8(dst, 0);
1.1       root     1739:                RegDY = (RegDY & 0xffffff00) | dst;
                   1740:        } else if (n == 0x0e) {
                   1741:                // LINK.L A6,#<imm>
                   1742:                CYCLE2(6, 7);
                   1743:                // レジスタやスタックを変更する前にフェッチしないと、
                   1744:                // ページフォルトで再実行できなくなる
1.1.1.5 ! root     1745:                imm = fetch_32();
1.1       root     1746:                // ページフォルトに備えて保存する
1.1.1.5 ! root     1747:                save_reg_pd(7);
        !          1748:                push_32(reg.A[6]);
        !          1749:                reg.A[6] = reg.A[7];
        !          1750:                reg.A[7] += imm;
1.1       root     1751:        } else if (n < 16) {
                   1752:                // LINK.L An,#<imm>
                   1753:                CYCLE2(6, 7);
                   1754:                // レジスタやスタックを変更する前にフェッチしないと、
                   1755:                // ページフォルトで再実行できなくなる
1.1.1.5 ! root     1756:                imm = fetch_32();
1.1       root     1757:                // ページフォルトに備えて保存する
1.1.1.5 ! root     1758:                save_reg_pd(7);
        !          1759:                push_32(RegAY);
        !          1760:                RegAY = reg.A[7];
        !          1761:                reg.A[7] += imm;
1.1       root     1762:        } else {
                   1763:                // NBCD.B <ea>
                   1764:                CYCLE(6);
1.1.1.5 ! root     1765:                uint32 ea = cea_data_8();
        !          1766:                uint32 dst = read_8(ea);
        !          1767:                dst = ACC.sbcd_8(dst, 0);
        !          1768:                write_8(ea, dst);
1.1       root     1769:        }
                   1770: }
                   1771: 
                   1772: // %0100_100001_000yyy SWAP.W Dy
                   1773: // %0100_100001_001nnn BKPT #<imm>
                   1774: // %0100_100001_mmmrrr PEA.L <ea>
                   1775: OP_DEF(pea)
                   1776: {
1.1.1.5 ! root     1777:        uint n = ir & 0x3f;
1.1       root     1778: 
                   1779:        if (n < 8) {
                   1780:                // SWAP.W Dy
                   1781:                CYCLE(4);
1.1.1.5 ! root     1782:                reg.D[n] = (reg.D[n] << 16) | (reg.D[n] >> 16);
        !          1783:                ACC.move_32(reg.D[n]);
1.1       root     1784:        } else if (n < 16) {
                   1785:                // BKPT #<imm>
                   1786:                // ブレークポイント・アクノリッジサイクルに応答するデバイスはないので
                   1787:                // 常に不当命令にする。
                   1788:                CYCLE(9);       // ?
1.1.1.5 ! root     1789:                op_illegal();
1.1       root     1790:        } else {
                   1791:                // PEA.L <ea>
                   1792:                CYCLE(4);
1.1.1.5 ! root     1793:                uint32 ea = cea_ctrl();
1.1       root     1794:                // ページフォルトに備えて保存する
1.1.1.5 ! root     1795:                save_reg_pd(7);
        !          1796:                push_32(ea);
1.1       root     1797:        }
                   1798: }
                   1799: 
                   1800: // MOVEM.[WL] <list>,<ea> の共通部分。
                   1801: // bytesize は1レジスタ分のサイズ、.Wなら2、.Lなら4。
1.1.1.5 ! root     1802: // 本当はテンプレートにしたい。
        !          1803: void
        !          1804: MPU680x0Device::ops_movem_list_ea(int bytesize)
1.1       root     1805: {
                   1806:        uint32 ea;
                   1807:        int regcount;
                   1808: 
                   1809:        // 不当な第1ワードを弾く
                   1810: #define INVALID(x)     (0xffULL << (56 - ((x) * 8)))
                   1811:        const uint64 valid =
                   1812:                INVALID(0)      // Dn
                   1813:          | INVALID(1)  // An
                   1814:          | INVALID(3)  // (An)+
                   1815:          | 0x3fL;              // (PC)...
1.1.1.5 ! root     1816:        if ((int64)(valid << (ir & 0x3f)) < 0) {
        !          1817:                op_illegal();
1.1       root     1818:                return;
                   1819:        }
                   1820: 
                   1821:        // 第2ワードは EA が正当な場合のみ EA より先にフェッチ
1.1.1.5 ! root     1822:        ir2 = fetch_16();
1.1       root     1823: 
                   1824:        // EA 取得。MOVEM だけ別対応
                   1825:        // |  M -WXZ  | MOVEM list,<ea>
                   1826:        // だが、不当 EA はすでに弾いてあるので cea_data でいい
                   1827:        if (bytesize == 2) {
1.1.1.5 ! root     1828:                ea = cea_data_16();
1.1       root     1829:        } else {
1.1.1.5 ! root     1830:                ea = cea_data_32();
1.1       root     1831:        }
                   1832: 
                   1833:        regcount = 0;
1.1.1.5 ! root     1834:        uint list = ir2;
        !          1835:        if (eamode(ir) == 4/*-(An)*/) {
1.1       root     1836:                // -(An) の場合 reglist の格納順が逆(転送順は LSB から)
                   1837:                // bit15                                      bit0
                   1838:                // D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 A4 A5 A6 A7
                   1839:                while (list) {
                   1840:                        int ctz = __builtin_ctz(list);
                   1841:                        if (bytesize == 2) {
1.1.1.5 ! root     1842:                                write_16(ea, reg.R[15 - ctz] & 0xffff);
1.1       root     1843:                        } else {
1.1.1.5 ! root     1844:                                write_32(ea, reg.R[15 - ctz]);
1.1       root     1845:                        }
                   1846:                        ea -= bytesize;
                   1847:                        regcount++;
                   1848:                        // 処理した最下位ビットを落とす
                   1849:                        list &= list - 1;
                   1850:                }
                   1851:                // ea は一つ行き過ぎるので補正
                   1852:                RegAY = ea + bytesize;
                   1853:        } else {
                   1854:                // LSB 側から転送
                   1855:                // bit15                                      bit0
                   1856:                // A7 A6 A5 A4 A4 A2 A1 A0 D7 D6 D5 D4 D3 D2 D1 D0
                   1857:                while (list) {
                   1858:                        int ctz = __builtin_ctz(list);
                   1859:                        if (bytesize == 2) {
1.1.1.5 ! root     1860:                                write_16(ea, reg.R[ctz] & 0xffff);
1.1       root     1861:                        } else {
1.1.1.5 ! root     1862:                                write_32(ea, reg.R[ctz]);
1.1       root     1863:                        }
                   1864:                        ea += bytesize;
                   1865:                        regcount++;
                   1866:                        // 処理した最下位ビットを落とす
                   1867:                        list &= list - 1;
                   1868:                }
                   1869:        }
                   1870: 
                   1871:        CYCLE(4 + 2 * regcount);
                   1872: }
                   1873: 
                   1874: // %0100_100010_000yyy EXT.W Dy
                   1875: // %0100_100010_mmmrrr MOVEM.W <list>,<ea>
                   1876: OP_DEF(movem_w_mem)
                   1877: {
1.1.1.5 ! root     1878:        uint n = ir & 0x3f;
1.1       root     1879: 
                   1880:        if (n < 8) {
                   1881:                // EXT.W Dy
                   1882:                CYCLE(4);
                   1883:                uint16 data = (int16)(int8)(RegDY & 0xff);
1.1.1.5 ! root     1884:                ACC.move_16(data);
1.1       root     1885:                RegDY = (RegDY & 0xffff0000) | data;
                   1886:        } else {
                   1887:                // MOVEM.W <list>,<ea>
1.1.1.5 ! root     1888:                ops_movem_list_ea(2);
1.1       root     1889:        }
                   1890: }
                   1891: 
                   1892: // %0100_100011_000yyy EXT.L Dy
                   1893: // %0100_100011_mmmrrr MOVEM.L <list>,<ea>
                   1894: OP_DEF(movem_l_mem)
                   1895: {
1.1.1.5 ! root     1896:        uint n = ir & 0x3f;
1.1       root     1897: 
                   1898:        if (n < 8) {
                   1899:                // EXT.L Dy
                   1900:                CYCLE(4);
                   1901:                RegDY = (int32)(int16)(RegDY & 0x0000ffff);
1.1.1.5 ! root     1902:                ACC.move_32(RegDY);
1.1       root     1903:        } else {
                   1904:                // MOVEM.L <list>,<ea>
1.1.1.5 ! root     1905:                ops_movem_list_ea(4);
1.1       root     1906:        }
                   1907: }
                   1908: 
                   1909: // %0100_101000_mmmrrr TST.B <ea>
                   1910: OP_DEF(tst_b)
                   1911: {
                   1912:        CYCLE(2);
1.1.1.5 ! root     1913:        uint32 data = fea_all_8();
        !          1914:        ACC.move_8(data);
1.1       root     1915: }
                   1916: 
                   1917: // %0100_101001_mmmrrr TST.W <ea>
                   1918: OP_DEF(tst_w)
                   1919: {
                   1920:        CYCLE(2);
1.1.1.5 ! root     1921:        uint32 data = fea_all_16();
        !          1922:        ACC.move_16(data);
1.1       root     1923: }
                   1924: 
                   1925: // %0100_101010_mmmrrr TST.L <ea>
                   1926: OP_DEF(tst_l)
                   1927: {
                   1928:        CYCLE(2);
1.1.1.5 ! root     1929:        uint32 data = fea_all_32();
        !          1930:        ACC.move_32(data);
1.1       root     1931: }
                   1932: 
                   1933: // %0100_101011_mmmrrr TAS.B <ea>
                   1934: // %0100_101011_111100 ILLEGAL
                   1935: OP_DEF(tas)
                   1936: {
1.1.1.5 ! root     1937:        uint n = ir & 0x3f;
1.1       root     1938: 
                   1939:        if (n < 8) {
                   1940:                // TAS.B Dn
                   1941:                // リード・モディファイ・ライトという概念はない
                   1942:                CYCLE(4);
1.1.1.5 ! root     1943:                uint32 data = reg.D[n];
        !          1944:                ACC.move_8(data);
        !          1945:                reg.D[n] |= 0x80;
1.1       root     1946:        } else if (n == 0x3c) {
                   1947:                // ILLEGAL
1.1.1.5 ! root     1948:                op_illegal();
1.1       root     1949:        } else {
                   1950:                // TAS.B <ea>
                   1951:                // リード・モディファイ・ライトという概念はない
                   1952:                CYCLE(12);
1.1.1.5 ! root     1953:                uint32 ea = cea_data_8();
        !          1954:                uint32 data = read_8(ea);
        !          1955:                ACC.move_8(data);
        !          1956:                write_8(ea, (data | 0x80));
1.1       root     1957:        }
                   1958: }
                   1959: 
                   1960: // %0100_110000_mmmrrr MUL{U,S}.L <ea>,Dl
                   1961: OP_DEF(mul)
                   1962: {
                   1963:        // 2ワード目
                   1964:        // %0LLL_Ss0000_000HHH
                   1965:        //   +++ ||        +++- Dh
                   1966:        //    |  |+------------ %1:64bit, %0:32bit
                   1967:        //    |  +------------- %1:MULS, %0:MULU
                   1968:        //    +---------------- Dl
1.1.1.5 ! root     1969:        ir2 = fetch_16();
        !          1970:        int h = ir2 & 7;
        !          1971:        int l = (ir2 >> 12) & 7;
1.1       root     1972: 
                   1973:        CYCLE(44);      // XXX これは本当は最大値だけど
1.1.1.5 ! root     1974:        switch ((ir2 >> 10) & 3) {
1.1       root     1975:         case 0:
                   1976:         {
                   1977:                // MULU.L <ea>,Dl
1.1.1.5 ! root     1978:                uint32 src = fea_data_32();
        !          1979:                uint32 dst = reg.D[l];
        !          1980:                reg.D[l] = ACC.mulu_32(src, dst);
1.1       root     1981:                break;
                   1982:         }
                   1983: 
                   1984:         case 1:
                   1985:         {
                   1986:                // MULU.L <ea>,Dh:Dl
1.1.1.5 ! root     1987:                uint32 src = fea_data_32();
        !          1988:                uint32 dst = reg.D[l];
        !          1989:                uint64 res = ACC.mulu_64(src, dst);
1.1       root     1990:                // h == l の時は未定義なので考えない。
1.1.1.5 ! root     1991:                reg.D[h] = res >> 32;
        !          1992:                reg.D[l] = res;
1.1       root     1993:                break;
                   1994:         }
                   1995: 
                   1996:         case 2:
                   1997:         {
                   1998:                // MULS.L <ea>,Dl
1.1.1.5 ! root     1999:                uint32 src = fea_data_32();
        !          2000:                uint32 dst = reg.D[l];
        !          2001:                reg.D[l] = ACC.muls_32(src, dst);
1.1       root     2002:                break;
                   2003:         }
                   2004: 
                   2005:         case 3:
                   2006:         {
                   2007:                // MULS.L <ea>,Dh:Dl
1.1.1.5 ! root     2008:                uint32 src = fea_data_32();
        !          2009:                uint32 dst = reg.D[l];
        !          2010:                uint64 res = ACC.muls_64(src, dst);
1.1       root     2011:                // h == l の時は未定義なので考えない。
1.1.1.5 ! root     2012:                reg.D[h] = res >> 32;
        !          2013:                reg.D[l] = res;
1.1       root     2014:                break;
                   2015:         }
                   2016: 
                   2017:         default:
                   2018:                __unreachable();
                   2019:        }
                   2020: }
                   2021: 
1.1.1.5 ! root     2022: // DIVU.L <ea>,Dq
        !          2023: // DIVUL.L <ea>,Dr:Dq
        !          2024: void
        !          2025: MPU680x0Device::ops_divu_32_32(int r, int q)
        !          2026: {
        !          2027:        CYCLE(78);      // XXX これは本当は最大値だけど
        !          2028: 
        !          2029:        uint32 src = fea_data_32();
        !          2030:        uint32 dst = reg.D[q];
        !          2031: 
        !          2032:        if (src == 0) {
        !          2033:                // ゼロ除算の場合、
        !          2034:                // X は変化しない
        !          2035:                // C は常にクリア
        !          2036:                // N,Z,V は未定義
        !          2037:                CCR.SetC(false);
        !          2038:                Exception(M68K::EXCEP_ZERODIV);
        !          2039:                return;
        !          2040:        }
        !          2041:        uint32 quo = dst / src;
        !          2042:        uint32 rem = dst % src;
        !          2043:        // このケースでオーバーフローは起きないはず
        !          2044: 
        !          2045:        // 正常の場合、
        !          2046:        // X は変化しない
        !          2047:        // V, C はクリア
        !          2048:        // N, Z は quo の結果。
        !          2049:        // r == q の場合 quo が残るので、rem を先に書く
        !          2050:        reg.D[r] = rem;
        !          2051:        reg.D[q] = quo;
        !          2052:        ACC.move_32(quo);
        !          2053: }
        !          2054: 
        !          2055: // DIVU.L <ea>,Dr:Dq
        !          2056: void
        !          2057: MPU680x0Device::ops_divu_64_32(int r, int q)
        !          2058: {
        !          2059:        CYCLE(78);      // XXX これは本当は最大値だけど
        !          2060: 
        !          2061:        uint32 src = fea_data_32();
        !          2062:        uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q];
        !          2063: 
        !          2064:        if (src == 0) {
        !          2065:                // ゼロ除算の場合、
        !          2066:                // X は変化しない
        !          2067:                // C は常にクリア
        !          2068:                // N,Z,V は未定義
        !          2069:                CCR.SetC(false);
        !          2070:                Exception(M68K::EXCEP_ZERODIV);
        !          2071:                return;
        !          2072:        }
        !          2073:        uint64 q64 = dst / src;
        !          2074:        if (q64 > 0xffffffffUL) {
        !          2075:                // オーバーフローの場合、
        !          2076:                // X は変化しない
        !          2077:                // N,Z は未定義
        !          2078:                // V はセット
        !          2079:                // C は常にクリア
        !          2080:                CCR.SetV(true);
        !          2081:                CCR.SetC(false);
        !          2082:                return;
        !          2083:        }
        !          2084:        uint32 quo = q64;
        !          2085:        uint32 rem = dst % src;
        !          2086: 
        !          2087:        // 正常の場合、
        !          2088:        // X は変化しない
        !          2089:        // V, C はクリア
        !          2090:        // N, Z は quo の結果。
        !          2091:        // r == q の場合 quo が残るので、rem を先に書く
        !          2092:        reg.D[r] = rem;
        !          2093:        reg.D[q] = quo;
        !          2094:        ACC.move_32(quo);
        !          2095: }
        !          2096: 
        !          2097: // DIVS.L <ea>,Dq
        !          2098: // DIVSL.L <ea>,Dr:Dq
        !          2099: void
        !          2100: MPU680x0Device::ops_divs_32_32(int r, int q)
        !          2101: {
        !          2102:        CYCLE(90);      // XXX これは本当は最大値だけど
        !          2103: 
        !          2104:        uint32 src = fea_data_32();
        !          2105:        uint32 dst = reg.D[q];
        !          2106: 
        !          2107:        if (src == 0) {
        !          2108:                // ゼロ除算の場合、
        !          2109:                // X は変化しない
        !          2110:                // C は常にクリア
        !          2111:                // N,Z,V は未定義
        !          2112:                CCR.SetC(false);
        !          2113:                Exception(M68K::EXCEP_ZERODIV);
        !          2114:                return;
        !          2115:        }
        !          2116: 
        !          2117:        // ホストでオーバーフローが起きるのはこのケースのみ
        !          2118:        if (dst == INT32_MIN && src == -1) {
        !          2119:                // オーバーフローの場合、
        !          2120:                // X は変化しない
        !          2121:                // N,Z は未定義
        !          2122:                // V はセット
        !          2123:                // C は常にクリア
        !          2124:                CCR.SetV(true);
        !          2125:                CCR.SetC(false);
        !          2126:                return;
        !          2127:        }
        !          2128: 
        !          2129:        uint32 quo = (int32)dst / (int32)src;
        !          2130:        uint32 rem = (int32)dst % (int32)src;
        !          2131:        // ここでオーバーフローは起きない
        !          2132: 
        !          2133:        // 正常の場合、
        !          2134:        // X は変化しない
        !          2135:        // V, C はクリア
        !          2136:        // N, Z は quo の結果。
        !          2137:        // r == q の場合 quo が残るので、rem を先に書く
        !          2138:        reg.D[r] = rem;
        !          2139:        reg.D[q] = quo;
        !          2140:        ACC.move_32(quo);
        !          2141: }
        !          2142: 
        !          2143: // DIVSL.L
        !          2144: void
        !          2145: MPU680x0Device::ops_divs_64_32(int r, int q)
        !          2146: {
        !          2147:        CYCLE(90);      // XXX これは本当は最大値だけど
        !          2148: 
        !          2149:        uint32 src = fea_data_32();
        !          2150:        uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q];
        !          2151: 
        !          2152:        if (src == 0) {
        !          2153:                // ゼロ除算の場合、
        !          2154:                // X は変化しない
        !          2155:                // C は常にクリア
        !          2156:                // N,Z,V は未定義
        !          2157:                CCR.SetC(false);
        !          2158:                Exception(M68K::EXCEP_ZERODIV);
        !          2159:                return;
        !          2160:        }
        !          2161: 
        !          2162:        // ホストでオーバーフローが起きるのはこのケースのみ
        !          2163:        if (dst == INT64_MIN && src == -1) {
        !          2164:                // オーバーフローの場合、
        !          2165:                // X は変化しない
        !          2166:                // N,Z は未定義
        !          2167:                // V はセット
        !          2168:                // C は常にクリア
        !          2169:                CCR.SetV(true);
        !          2170:                CCR.SetC(false);
        !          2171:                return;
        !          2172:        }
        !          2173: 
        !          2174:        int64 sq64 = (int64)dst / (int32)src;
        !          2175:        if ((int32)sq64 != sq64) {
        !          2176:                // オーバーフロー
        !          2177:                CCR.SetV(true);
        !          2178:                CCR.SetC(false);
        !          2179:                return;
        !          2180:        }
        !          2181:        uint32 quo = (uint32)sq64;
        !          2182:        uint32 rem = (int64)dst % (int32)src;
        !          2183: 
        !          2184:        // 正常の場合、
        !          2185:        // X は変化しない
        !          2186:        // V, C はクリア
        !          2187:        // N, Z は quo の結果。
        !          2188:        // r == q の場合 quo が残るので、rem を先に書く
        !          2189:        reg.D[r] = rem;
        !          2190:        reg.D[q] = quo;
        !          2191:        ACC.move_32(quo);
        !          2192: }
        !          2193: 
1.1       root     2194: // %0100_110001_mmmrrr DIVU.L <ea>,Dq
                   2195: // %0100_110001_mmmrrr DIVU.L <ea>,Dr:Dq
                   2196: // %0100_110001_mmmrrr DIVUL.L <ea>,Dr:Dq
                   2197: // %0100_110001_mmmrrr DIVS.L <ea>,Dq
                   2198: // %0100_110001_mmmrrr DIVS.L <ea>,Dr:Dq
                   2199: // %0100_110001_mmmrrr DIVSL.L <ea>,Dr:Dq
                   2200: OP_DEF(div)
                   2201: {
                   2202:        // 2ワード目
                   2203:        // %0QQQ_Ss0000_000RRR
                   2204:        //   +++ ||        +++- Dr
                   2205:        //    |  |+------------ %1:64bit, %0:32bit
                   2206:        //    |  +------------- %1:DIVS, %0:DIVU
                   2207:        //    +---------------- Dq
1.1.1.5 ! root     2208:        ir2 = fetch_16();
        !          2209:        int r = ir2 & 7;
        !          2210:        int q = (ir2 >> 12) & 7;
1.1       root     2211: 
1.1.1.5 ! root     2212:        switch ((ir2 >> 10) & 3) {
1.1       root     2213:         case 0:
1.1.1.5 ! root     2214:                ops_divu_32_32(r, q);
1.1       root     2215:                break;
1.1.1.5 ! root     2216:         case 1:
        !          2217:                ops_divu_64_32(r, q);
1.1       root     2218:                break;
                   2219:         case 2:
1.1.1.5 ! root     2220:                ops_divs_32_32(r, q);
1.1       root     2221:                break;
1.1.1.5 ! root     2222:         case 3:
        !          2223:                ops_divs_64_32(r, q);
1.1       root     2224:                break;
                   2225:         default:
                   2226:                __unreachable();
                   2227:        }
                   2228: }
                   2229: 
1.1.1.5 ! root     2230: void
        !          2231: MPU680x0Device::ops_movem_ea_list(int bytesize)
1.1       root     2232: {
                   2233:        uint32 ea;
                   2234:        int regcount;
                   2235:        bool anpi = false;
                   2236: 
1.1.1.5 ! root     2237:        ir2 = fetch_16();
1.1       root     2238: 
                   2239:        // EA 取得。MOVEM だけ別対応
                   2240:        // |  M+ WXZP | MOVEM <ea>,list
1.1.1.5 ! root     2241:        switch (eamode(ir)) {
1.1       root     2242:         case 2:        // (An)
1.1.1.5 ! root     2243:                ea = cea_anin(eanum(ir));
1.1       root     2244:                break;
                   2245:         case 3:        // (An)+
                   2246:                if (bytesize == 2) {
1.1.1.5 ! root     2247:                        ea = cea_anpi_16(eanum(ir));
1.1       root     2248:                } else {
1.1.1.5 ! root     2249:                        ea = cea_anpi_32(eanum(ir));
1.1       root     2250:                }
                   2251:                anpi = true;
                   2252:                break;
                   2253:         case 5:        // d16(An)
1.1.1.5 ! root     2254:                ea = cea_andi(eanum(ir));
1.1       root     2255:                break;
                   2256:         case 6:        // (An,IX)
1.1.1.5 ! root     2257:                ea = cea_anix(eanum(ir));
1.1       root     2258:                break;
                   2259:         case 7:
1.1.1.5 ! root     2260:                switch (eanum(ir)) {
1.1       root     2261:                 case 0:        // Abs.W
1.1.1.5 ! root     2262:                        ea = cea_absw();
1.1       root     2263:                        break;
                   2264:                 case 1:        // Abs.L
1.1.1.5 ! root     2265:                        ea = cea_absl();
1.1       root     2266:                        break;
                   2267:                 case 2:        // d16(PC)
1.1.1.5 ! root     2268:                        ea = cea_pcdi();
1.1       root     2269:                        break;
                   2270:                 case 3:        // (PC,IX)
1.1.1.5 ! root     2271:                        ea = cea_pcix();
1.1       root     2272:                        break;
                   2273:                 default:
1.1.1.5 ! root     2274:                        op_illegal();
1.1       root     2275:                        return;
                   2276:                }
                   2277:                break;
                   2278:         default:
1.1.1.5 ! root     2279:                op_illegal();
1.1       root     2280:                return;
                   2281:        }
                   2282: 
                   2283: // XXX レジスタリストに表れて、ea オペランドに出てくる
                   2284: // レジスタはデータレジスタIX も含めて全部保存しておく必要がある。
                   2285: 
                   2286:        regcount = 0;
1.1.1.5 ! root     2287:        uint list = ir2;
1.1       root     2288:        while (list) {
                   2289:                uint32 data;
                   2290:                if (bytesize == 2) {
1.1.1.5 ! root     2291:                        data = (int32)(int16)read_16(ea);
1.1       root     2292:                } else {
1.1.1.5 ! root     2293:                        data = read_32(ea);
1.1       root     2294:                }
                   2295:                ea += bytesize;
                   2296:                regcount++;
                   2297:                int ctz = __builtin_ctz(list);
1.1.1.5 ! root     2298:                reg.R[ctz] = data;
1.1       root     2299:                // clear LSB bits
                   2300:                list &= ((~1U) << ctz);
                   2301:        }
                   2302:        // (An)+ なら An を更新
                   2303:        if (anpi) {
                   2304:                RegAY = ea;
                   2305:        }
                   2306: 
                   2307:        CYCLE(8 + 4 * regcount);
                   2308: }
                   2309: 
                   2310: // %0100_110010_mmmrrr MOVEM.W <ea>,<list>
                   2311: OP_DEF(movem_w)
                   2312: {
1.1.1.5 ! root     2313:        ops_movem_ea_list(2);
1.1       root     2314: }
                   2315: 
                   2316: // %0100_110011_mmmrrr MOVEM.L <ea>,<list>
                   2317: OP_DEF(movem_l)
                   2318: {
1.1.1.5 ! root     2319:        ops_movem_ea_list(4);
1.1       root     2320: }
                   2321: 
                   2322: // MOVEC.L Rc,Rn
1.1.1.5 ! root     2323: void
        !          2324: MPU680x0Device::ops_movec_rc_rn()
1.1       root     2325: {
                   2326:        SUPERVISOR_OP;
                   2327: 
                   2328:        CYCLE(6);
1.1.1.5 ! root     2329:        ir2 = fetch_16();
        !          2330:        int n = ir2 >> 12;
        !          2331:        int c = ir2 & 0xfff;
1.1       root     2332:        switch (c) {
                   2333:         case 0x000:
1.1.1.5 ! root     2334:                reg.R[n] = reg.sfc;
1.1       root     2335:                return;
                   2336:         case 0x001:
1.1.1.5 ! root     2337:                reg.R[n] = reg.dfc;
1.1       root     2338:                return;
                   2339:         case 0x002:
1.1.1.5 ! root     2340:                reg.R[n] = reg.cacr;
1.1       root     2341:                return;
                   2342:         case 0x800:
1.1.1.5 ! root     2343:                reg.R[n] = reg.usp;
1.1       root     2344:                return;
                   2345:         case 0x801:
1.1.1.5 ! root     2346:                reg.R[n] = reg.vbr;
1.1       root     2347:                return;
                   2348:         case 0x802:
1.1.1.5 ! root     2349:                reg.R[n] = reg.caar;
1.1       root     2350:                return;
                   2351:         case 0x803:
1.1.1.5 ! root     2352:                if (reg.m) {
        !          2353:                        reg.R[n] = reg.A[7];
1.1       root     2354:                } else {
1.1.1.5 ! root     2355:                        reg.R[n] = reg.msp;
1.1       root     2356:                }
                   2357:                return;
                   2358:         case 0x804:
1.1.1.5 ! root     2359:                if (reg.m) {
        !          2360:                        reg.R[n] = reg.isp;
1.1       root     2361:                } else {
1.1.1.5 ! root     2362:                        reg.R[n] = reg.A[7];
1.1       root     2363:                }
                   2364:                return;
                   2365:         default:
                   2366:                break;
                   2367:        }
1.1.1.5 ! root     2368:        op_illegal();
1.1       root     2369: }
                   2370: 
                   2371: // MOVEC.L Rn,Rc
1.1.1.5 ! root     2372: void
        !          2373: MPU680x0Device::ops_movec_rn_rc()
1.1       root     2374: {
                   2375:        SUPERVISOR_OP;
                   2376: 
1.1.1.5 ! root     2377:        ir2 = fetch_16();
        !          2378:        int n = ir2 >> 12;
        !          2379:        int c = ir2 & 0xfff;
1.1       root     2380:        switch (c) {
                   2381:         case 0x000:
                   2382:                CYCLE(12);
1.1.1.5 ! root     2383:                reg.sfc = reg.R[n];
1.1       root     2384:                return;
                   2385:         case 0x001:
                   2386:                CYCLE(12);
1.1.1.5 ! root     2387:                reg.dfc = reg.R[n];
1.1       root     2388:                return;
                   2389:         case 0x002:
                   2390:                CYCLE(12);
1.1.1.5 ! root     2391:                reg.cacr = reg.R[n];
1.1       root     2392:                return;
                   2393:         case 0x800:
                   2394:                CYCLE(6);
1.1.1.5 ! root     2395:                reg.usp = reg.R[n];
1.1       root     2396:                return;
                   2397:         case 0x801:
                   2398:                CYCLE(6);
1.1.1.5 ! root     2399:                reg.vbr = reg.R[n];
1.1       root     2400:                return;
                   2401:         case 0x802:
                   2402:                CYCLE(6);
1.1.1.5 ! root     2403:                reg.caar = reg.R[n];
1.1       root     2404:                return;
                   2405:         case 0x803:
                   2406:                CYCLE(6);
1.1.1.5 ! root     2407:                if (reg.m) {
        !          2408:                        reg.A[7] = reg.R[n];
1.1       root     2409:                } else {
1.1.1.5 ! root     2410:                        reg.msp = reg.R[n];
1.1       root     2411:                }
                   2412:                return;
                   2413:         case 0x804:
                   2414:                CYCLE(6);
1.1.1.5 ! root     2415:                if (reg.m) {
        !          2416:                        reg.isp = reg.R[n];
1.1       root     2417:                } else {
1.1.1.5 ! root     2418:                        reg.A[7] = reg.R[n];
1.1       root     2419:                }
                   2420:                return;
                   2421:         default:
                   2422:                break;
                   2423:        }
1.1.1.5 ! root     2424:        op_illegal();
1.1       root     2425: }
                   2426: 
                   2427: // %0100_111001_00nnnn TRAP #<vector>
                   2428: // %0100_111001_010yyy LINK.W Ay,#<imm>
                   2429: // %0100_111001_011yyy UNLK Ay
                   2430: // %0100_111001_100yyy MOVE.L Ay,USP
                   2431: // %0100_111001_101yyy MOVE.L USP,Ay
                   2432: // %0100_111001_110000 RESET
                   2433: // %0100_111001_110001 NOP
                   2434: // %0100_111001_110010 STOP #<imm>
                   2435: // %0100_111001_110011 RTE
                   2436: // %0100_111001_110100 RTD #<imm>
                   2437: // %0100_111001_110101 RTS
                   2438: // %0100_111001_110110 TRAPV
                   2439: // %0100_111001_110111 RTR
                   2440: // %0100_111001_111010 MOVEC.L Rc,Rn
                   2441: // %0100_111001_111011 MOVEC.L Rn,Rc
                   2442: OP_DEF(trap)
                   2443: {
1.1.1.5 ! root     2444:        uint n = ir & 0x3f;
1.1       root     2445:        int32 imm;
                   2446: 
                   2447:        switch (n) {
                   2448:         case 0x00 ... 0x0f:// TRAP #<vector>
                   2449:                CYCLE2(18, 20);
                   2450:                // TRAP#N 例外
1.1.1.5 ! root     2451:                Exception(M68K::EXCEP_TRAP0 + n);
1.1       root     2452:                return;
                   2453: 
                   2454:         case 0x10:
                   2455:         case 0x11:
                   2456:         case 0x12:
                   2457:         case 0x13:
                   2458:         case 0x14:
                   2459:         case 0x15:
                   2460:         case 0x17:                     // LINK.W Ay,#<imm>
                   2461:                CYCLE2(4, 5);
                   2462:                // レジスタやスタックを変更する前にフェッチとセーブをしないと、
                   2463:                // ページフォルトで再実行できなくなる
1.1.1.5 ! root     2464:                imm = (int32)(int16)fetch_16();
        !          2465:                save_reg_pd(7);
        !          2466:                push_32(RegAY);
        !          2467:                RegAY = reg.A[7];
        !          2468:                reg.A[7] += imm;
1.1       root     2469:                return;
                   2470:         case 0x16:                     // LINK.W A6,#<imm>
                   2471:                // LINK はほぼ A6 なのでこいつだけ展開してみる
                   2472:                CYCLE2(4, 5);
                   2473:                // レジスタやスタックを変更する前にフェッチとセーブをしないと、
                   2474:                // ページフォルトで再実行できなくなる
1.1.1.5 ! root     2475:                imm = (int32)(int16)fetch_16();
        !          2476:                save_reg_pd(7);
        !          2477:                push_32(reg.A[6]);
        !          2478:                reg.A[6] = reg.A[7];
        !          2479:                reg.A[7] += imm;
1.1       root     2480:                return;
                   2481: 
                   2482:         case 0x18:
                   2483:         case 0x19:
                   2484:         case 0x1a:
                   2485:         case 0x1b:
                   2486:         case 0x1c:
                   2487:         case 0x1d:
                   2488:         case 0x1f:                     // UNLK Ay
                   2489:                CYCLE(5);
                   2490:                // ページフォルトに備えて保存する
1.1.1.5 ! root     2491:                save_reg_pi(7);
        !          2492:                reg.A[7] = RegAY;
        !          2493:                RegAY = pop_32();
1.1       root     2494:                return;
                   2495:         case 0x1e:                     // UNLK A6
                   2496:                // UNLK はほぼ A6 なのでこいつだけ展開してみる
                   2497:                CYCLE(5);
                   2498:                // ページフォルトに備えて保存する
1.1.1.5 ! root     2499:                save_reg_pi(7);
        !          2500:                reg.A[7] = reg.A[6];
        !          2501:                reg.A[6] = pop_32();
1.1       root     2502:                return;
                   2503: 
                   2504:         case 0x20:
                   2505:         case 0x21:
                   2506:         case 0x22:
                   2507:         case 0x23:
                   2508:         case 0x24:
                   2509:         case 0x25:
                   2510:         case 0x26:
                   2511:         case 0x27:                     // MOVE.L Ay,USP
                   2512:                SUPERVISOR_OP;
                   2513:                CYCLE(4);
1.1.1.5 ! root     2514:                reg.usp = RegAY;
1.1       root     2515:                return;
                   2516: 
                   2517:         case 0x28:
                   2518:         case 0x29:
                   2519:         case 0x2a:
                   2520:         case 0x2b:
                   2521:         case 0x2c:
                   2522:         case 0x2d:
                   2523:         case 0x2e:
                   2524:         case 0x2f:                     // MOVE.L USP,Ay
                   2525:                SUPERVISOR_OP;
                   2526:                CYCLE(4);
1.1.1.5 ! root     2527:                RegAY = reg.usp;
1.1       root     2528:                return;
                   2529: 
                   2530:         case 0x30:                     // RESET
                   2531:                CYCLE(518);
1.1.1.5 ! root     2532:                ops_reset();
1.1       root     2533:                return;
                   2534: 
                   2535:         case 0x31:                     // NOP
                   2536:                CYCLE(2);
                   2537:                // XXX ほんとは何かするらしいけど
                   2538:                return;
                   2539: 
                   2540:         case 0x32:                     // STOP #<imm>
                   2541:                SUPERVISOR_OP;
                   2542:                CYCLE(8);
1.1.1.5 ! root     2543:                ops_stop();
1.1       root     2544:                return;
                   2545: 
                   2546:         case 0x33:                     // RTE
1.1.1.4   root     2547:                SUPERVISOR_OP;
1.1.1.5 ! root     2548:                ops_rte();
1.1       root     2549:                return;
                   2550: 
                   2551:         case 0x34:                     // RTD #<imm>
                   2552:         {
                   2553:                CYCLE2(10, 12);
                   2554:                // ページフォルトに備えて保存する
1.1.1.5 ! root     2555:                save_reg_pi(7);
        !          2556:                uint32 disp = fetch_16();
        !          2557:                Jump(pop_32());
        !          2558:                reg.A[7] += (int32)(int16)disp;
1.1       root     2559:                return;
                   2560:         }
                   2561: 
                   2562:         case 0x35:                     // RTS
                   2563:                CYCLE2(9, 11);
                   2564:                // ページフォルトに備えて保存する
1.1.1.5 ! root     2565:                save_reg_pi(7);
        !          2566:                Jump(pop_32());
1.1       root     2567:                return;
                   2568: 
                   2569:         case 0x36:                     // TRAPV
                   2570:                if (CCR.IsV()) {
                   2571:                        CYCLE2(22, 24);
1.1.1.5 ! root     2572:                        Exception(M68K::EXCEP_TRAPV);
1.1       root     2573:                } else {
                   2574:                        CYCLE(4);
                   2575:                }
                   2576:                return;
                   2577: 
                   2578:         case 0x37:                     // RTR
                   2579:                CYCLE2(12, 14);
                   2580:                // ページフォルトに備えて保存する
1.1.1.5 ! root     2581:                save_reg_pi(7);
        !          2582:                CCR.Set(pop_16());
        !          2583:                Jump(pop_32());
1.1       root     2584:                return;
                   2585: 
                   2586:         case 0x3a:                     // MOVEC.L Rc,Rn
1.1.1.5 ! root     2587:                ops_movec_rc_rn();
1.1       root     2588:                return;
                   2589: 
                   2590:         case 0x3b:                     // MOVEC.L Rn,Rc
1.1.1.5 ! root     2591:                ops_movec_rn_rc();
1.1       root     2592:                return;
                   2593: 
                   2594:         default:
1.1.1.5 ! root     2595:                op_illegal();
1.1       root     2596:                return;
                   2597:        }
                   2598: }
                   2599: 
                   2600: // %0100_111010_mmmrrr JSR <ea>
                   2601: OP_DEF(jsr)
                   2602: {
                   2603:        CYCLE2(4, 7);
1.1.1.5 ! root     2604:        uint32 ea = cea_ctrl();
1.1       root     2605:        // ページフォルトに備えて保存する
1.1.1.5 ! root     2606:        save_reg_pd(7);
        !          2607:        push_32(reg.pc);
        !          2608:        Jump(ea);
1.1       root     2609: }
                   2610: 
                   2611: // %0100_111011_mmmrrr JMP <ea>
                   2612: OP_DEF(jmp)
                   2613: {
                   2614:        CYCLE2(4, 6);
                   2615:        // 実際には CEA ではなく JEA の実行時間を足すんだがまあいいか
1.1.1.5 ! root     2616:        uint32 ea = cea_ctrl();
        !          2617:        Jump(ea);
1.1       root     2618: }
                   2619: 
                   2620: // %0101_qqq000_mmmrrr ADDQ.B #qqq,<ea>
                   2621: OP_DEF(addq_b)
                   2622: {
1.1.1.5 ! root     2623:        uint n = ir & 0x3f;
1.1       root     2624: 
                   2625:        uint32 src = RegIRX;
                   2626:        src = (src == 0) ? 8 : src;
                   2627:        if (n < 8) {
                   2628:                // ADDQ.B #qqq,Dn
                   2629:                CYCLE(2);
1.1.1.5 ! root     2630:                uint32 data = ACC.add_8(src, reg.D[n] & 0xff);
        !          2631:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
1.1       root     2632:        } else {
                   2633:                // ADDQ.B #qqq,<ea>
                   2634:                CYCLE2(3, 4);
1.1.1.5 ! root     2635:                uint32 ea = cea_data_8();
        !          2636:                uint32 data = read_8(ea);
        !          2637:                data = ACC.add_8(src, data);
        !          2638:                write_8(ea, data);
1.1       root     2639:        }
                   2640: }
                   2641: 
                   2642: // %0101_qqq001_mmmrrr ADDQ.W #qqq,<ea>
                   2643: // %0101_qqq001_001yyy ADDQ.W #qqq,Ay (.Lと等価)
                   2644: OP_DEF(addq_w)
                   2645: {
1.1.1.5 ! root     2646:        uint n = ir & 0x3f;
1.1       root     2647: 
                   2648:        uint32 src = RegIRX;
                   2649:        src = (src == 0) ? 8 : src;
                   2650:        if (n < 8) {
                   2651:                // ADDQ.W #qqq,Dn
                   2652:                CYCLE(2);
1.1.1.5 ! root     2653:                uint32 data = ACC.add_16(src, reg.D[n] & 0xffff);
        !          2654:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
1.1       root     2655:        } else if (n < 16) {
                   2656:                // ADDQ.W #qqq,An は ADDQ.L と等価
                   2657:                // フラグは変化しない
                   2658:                CYCLE(2);
1.1.1.5 ! root     2659:                reg.R[n] += src;
1.1       root     2660:        } else {
                   2661:                // ADDQ.W #qqq,<ea>
                   2662:                CYCLE2(3, 4);
1.1.1.5 ! root     2663:                uint32 ea = cea_data_16();
        !          2664:                uint32 data = read_16(ea);
        !          2665:                data = ACC.add_16(src, data);
        !          2666:                write_16(ea, data);
1.1       root     2667:        }
                   2668: }
                   2669: 
                   2670: // %0101_qqq010_mmmrrr ADDQ.L #qqq,<ea>
                   2671: // %0101_qqq010_001yyy ADDQ.L #qqq,Ay
                   2672: OP_DEF(addq_l)
                   2673: {
1.1.1.5 ! root     2674:        uint n = ir & 0x3f;
1.1       root     2675: 
                   2676:        uint32 src = RegIRX;
                   2677:        src = (src == 0) ? 8 : src;
                   2678:        if (n < 8) {
                   2679:                // ADDQ.L #qqq,Dn
                   2680:                CYCLE(2);
1.1.1.5 ! root     2681:                reg.D[n] = ACC.add_32(src, reg.D[n]);
1.1       root     2682:        } else if (n < 16) {
                   2683:                // ADDQ.L #qqq,An
                   2684:                // フラグは変化しない
                   2685:                CYCLE(2);
1.1.1.5 ! root     2686:                reg.R[n] += src;
1.1       root     2687:        } else {
                   2688:                // ADDQ.L #qqq,<ea>
                   2689:                CYCLE2(3, 4);
1.1.1.5 ! root     2690:                uint32 ea = cea_data_32();
        !          2691:                uint32 data = read_32(ea);
        !          2692:                data = ACC.add_32(src, data);
        !          2693:                write_32(ea, data);
1.1       root     2694:        }
                   2695: }
                   2696: 
                   2697: // TRAPcc の共通部分。
1.1.1.5 ! root     2698: void
        !          2699: MPU680x0Device::ops_trapcc(uint cond)
1.1       root     2700: {
                   2701:        // 条件成立すれば例外。成立しなければ何もしない。
                   2702:        // いずれの場合もオペランドありの形態なら事前に読み飛ばしておくこと。
1.1.1.5 ! root     2703:        if (CCR.Cond(cond)) {
1.1       root     2704:                CYCLE2(22, 24);
1.1.1.5 ! root     2705:                Exception(M68K::EXCEP_TRAPV);
1.1       root     2706:        } else {
                   2707:                // サイクルを消費するだけ
                   2708:                CYCLE(4);
                   2709:        }
                   2710: }
                   2711: 
1.1.1.5 ! root     2712: // %0101_cccc11_mmmrrr Scc.B <ea>
        !          2713: // %0101_cccc11_001yyy DBcc.W Dy,<label>
        !          2714: // %0101_cccc11_111010 TRAPcc.W #<imm>
        !          2715: // %0101_cccc11_111011 TRAPcc.L #<imm>
        !          2716: // %0101_cccc11_111100 TRAPcc
        !          2717: // %0101_000111_001yyy DBRA.W Dy,<label>
        !          2718: OP_DEF(scc)
1.1       root     2719: {
1.1.1.5 ! root     2720:        uint n = ir & 0x3f;
        !          2721:        uint cond = (ir >> 8) & 0x0f;
1.1       root     2722: 
                   2723:        switch (n) {
                   2724:         case 0b000000 ... 0b000111:    // Scc.B Dn
                   2725:                CYCLE(4);
1.1.1.5 ! root     2726:                if (CCR.Cond(cond)) {
1.1       root     2727:                        RegDY |= 0xff;
                   2728:                } else {
                   2729:                        RegDY &= ~0xff;
                   2730:                }
                   2731:                return;
                   2732: 
                   2733:         case 0b001000 ... 0b001111:    // DBcc.W Dy,<label>
1.1.1.5 ! root     2734:                if (CCR.Cond(cond)) {
1.1       root     2735:                        // 真なら何もしない。disp を読み飛ばして次へ。
                   2736:                        CYCLE2(6, 8);
1.1.1.5 ! root     2737:                        fetch_16();
1.1       root     2738:                } else {
                   2739:                        // 偽の場合
                   2740: 
                   2741:                        // Dy.W を減算して(下位ワードに)書き戻し、Dy.W が -1 だったら
                   2742:                        // ループ終了。だが最適化のため、減算前の Dy.W が 0 の時は
                   2743:                        // 下位ワードを 0xffff にしてループ終了、そうでなければ Dy.L を
                   2744:                        // 減算するだけでいいはず。
                   2745: 
                   2746:                        uint16 data = RegDY;
                   2747:                        if (data == 0) {
                   2748:                                // ループ終了。disp を読み飛ばす
                   2749:                                CYCLE2(10, 13);
                   2750:                                RegDY |= 0x0000ffff;
1.1.1.5 ! root     2751:                                fetch_16();
1.1       root     2752:                        } else {
                   2753:                                CYCLE2(6, 8);
                   2754:                                RegDY--;
1.1.1.5 ! root     2755:                                uint32 origin = reg.pc;
        !          2756:                                int32 disp = (int32)(int16)fetch_16();
        !          2757:                                Jump(origin + disp);
1.1       root     2758:                        }
                   2759:                }
                   2760:                return;
                   2761: 
                   2762:         case 0b010000 ... 0b010111:    // Scc.B <ea>
                   2763:         case 0b011000 ... 0b011111:    // Scc.B <ea>
                   2764:         case 0b100000 ... 0b100111:    // Scc.B <ea>
                   2765:         case 0b101000 ... 0b101111:    // Scc.B <ea>
                   2766:         case 0b110000 ... 0b110111:    // Scc.B <ea>
                   2767:         case 0b111000:                                 // Scc.B <ea>
                   2768:         case 0b111001:                                 // Scc.B <ea>
                   2769:         {
                   2770:                CYCLE(5);
                   2771:                // 条件成立可否に関わらず EA は取得しないといけない
1.1.1.5 ! root     2772:                uint32 ea = cea_data_8();
1.1       root     2773:                uint32 data;
1.1.1.5 ! root     2774:                if (CCR.Cond(cond)) {
1.1       root     2775:                        data = 0xff;
                   2776:                } else {
                   2777:                        data = 0;
                   2778:                }
1.1.1.5 ! root     2779:                write_8(ea, data);
1.1       root     2780:                return;
                   2781:         }
                   2782: 
                   2783:         case 0b111010:         // TRAPcc.W #<imm>
                   2784:                // オペランドなしTRAPccに比べてすべてのケースで2サイクル多い
                   2785:                CYCLE(2);
1.1.1.5 ! root     2786:                fetch_16();
        !          2787:                ops_trapcc(cond);
1.1       root     2788:                return;
                   2789: 
                   2790:         case 0b111011:         // TRAPcc.L #<imm>
                   2791:                // オペランドなしTRAPccに比べてすべてのケースで4サイクル多い
                   2792:                CYCLE(4);
1.1.1.5 ! root     2793:                fetch_32();
        !          2794:                ops_trapcc(cond);
1.1       root     2795:                return;
                   2796: 
                   2797:         case 0b111100:         // TRAPcc
1.1.1.5 ! root     2798:                ops_trapcc(cond);
1.1       root     2799:                return;
                   2800: 
                   2801:         default:
                   2802:                OP_FUNC(illegal);
                   2803:                return;
                   2804:        }
                   2805: }
                   2806: 
                   2807: // %0101_qqq100_mmmrrr SUBQ.B #qqq,<ea>
                   2808: OP_DEF(subq_b)
                   2809: {
1.1.1.5 ! root     2810:        uint n = ir & 0x3f;
1.1       root     2811: 
                   2812:        uint32 src = RegIRX;
                   2813:        src = (src == 0) ? 8 : src;
                   2814:        if (n < 8) {
                   2815:                // SUBQ.B #qqq,Dn
                   2816:                CYCLE(2);
1.1.1.5 ! root     2817:                uint32 data = ACC.sub_8(src, reg.D[n] & 0xff);
        !          2818:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
1.1       root     2819:        } else {
                   2820:                // SUBQ.B #qqq,<ea>
                   2821:                CYCLE2(3, 4);
1.1.1.5 ! root     2822:                uint32 ea = cea_data_8();
        !          2823:                uint32 data = read_8(ea);
        !          2824:                data = ACC.sub_8(src, data);
        !          2825:                write_8(ea, data);
1.1       root     2826:        }
                   2827: }
                   2828: 
                   2829: // %0101_qqq101_mmmrrr SUBQ.W #qqq,<ea>
                   2830: // %0101_qqq101_001yyy SUBQ.W #qqq,Ay (.Lと等価)
                   2831: OP_DEF(subq_w)
                   2832: {
1.1.1.5 ! root     2833:        uint n = ir & 0x3f;
1.1       root     2834: 
                   2835:        uint32 src = RegIRX;
                   2836:        src = (src == 0) ? 8 : src;
                   2837:        if (n < 8) {
                   2838:                // SUBQ.W #qqq,Dn
                   2839:                CYCLE(2);
1.1.1.5 ! root     2840:                uint32 data = ACC.sub_16(src, reg.D[n] & 0xffff);
        !          2841:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
1.1       root     2842:        } else if (n < 16) {
                   2843:                // SUBQ.W #qqq,An は SUBQ.L と等価
                   2844:                // フラグは変化しない
                   2845:                CYCLE(2);
1.1.1.5 ! root     2846:                reg.R[n] -= src;
1.1       root     2847:        } else {
                   2848:                // SUBQ.W #qqq,<ea>
                   2849:                CYCLE2(3, 4);
1.1.1.5 ! root     2850:                uint32 ea = cea_data_16();
        !          2851:                uint32 data = read_16(ea);
        !          2852:                data = ACC.sub_16(src, data);
        !          2853:                write_16(ea, data);
1.1       root     2854:        }
                   2855: }
                   2856: 
                   2857: // %0101_qqq110_mmmrrr SUBQ.L #qqq,<ea>
                   2858: // %0101_qqq110_001yyy SUBQ.L #qqq,Ay
                   2859: OP_DEF(subq_l)
                   2860: {
1.1.1.5 ! root     2861:        uint n = ir & 0x3f;
1.1       root     2862: 
                   2863:        uint32 src = RegIRX;
                   2864:        src = (src == 0) ? 8 : src;
                   2865:        if (n < 8) {
                   2866:                // SUBQ.L #qqq,Dn
                   2867:                CYCLE(2);
1.1.1.5 ! root     2868:                reg.D[n] = ACC.sub_32(src, reg.D[n]);
1.1       root     2869:        } else if (n < 16) {
                   2870:                // SUBQ.L #qqq,An
                   2871:                // フラグは変化しない
                   2872:                CYCLE(2);
1.1.1.5 ! root     2873:                reg.R[n] -= src;
1.1       root     2874:        } else {
                   2875:                // SUBQ.L #qqq,<ea>
                   2876:                CYCLE2(3, 4);
1.1.1.5 ! root     2877:                uint32 ea = cea_data_32();
        !          2878:                uint32 data = read_32(ea);
        !          2879:                data = ACC.sub_32(src, data);
        !          2880:                write_32(ea, data);
1.1       root     2881:        }
                   2882: }
                   2883: 
1.1.1.5 ! root     2884: inline void
        !          2885: MPU680x0Device::ops_bra()
1.1       root     2886: {
1.1.1.5 ! root     2887:        CYCLE2(6, 8);
1.1       root     2888: 
1.1.1.5 ! root     2889:        uint32 origin = reg.pc;
        !          2890:        int32 disp = (int32)(int8)(ir & 0xff);
        !          2891:        if (disp == -1) {
        !          2892:                // Bcc.L
        !          2893:                disp = (int32)fetch_32();
        !          2894:        } else if (disp == 0) {
        !          2895:                // Bcc.W
        !          2896:                disp = (int32)(int16)fetch_16();
1.1       root     2897:        }
1.1.1.5 ! root     2898:        Jump(origin + disp);
1.1       root     2899: }
                   2900: 
                   2901: // %0110_000000_000000 BRA.W <label>
                   2902: // %0110_0000nn_nnnnnn BRA.B <label>
                   2903: // %0110_000011_111111 BRA.L <label>
                   2904: OP_DEF(bra)
                   2905: {
1.1.1.5 ! root     2906:        ops_bra();
1.1       root     2907: }
                   2908: 
                   2909: // %0110_000100_000000 BSR.W <label>
                   2910: // %0110_0001nn_nnnnnn BSR.B <label>
                   2911: // %0110_000111_111111 BSR.L <label>
                   2912: OP_DEF(bsr)
                   2913: {
                   2914:        CYCLE2(6, 9);
1.1.1.5 ! root     2915:        uint32 origin = reg.pc;
        !          2916:        int32 disp = (int32)(int8)(ir & 0xff);
1.1       root     2917:        if (disp == -1) {
                   2918:                // BSR.L <label>
1.1.1.5 ! root     2919:                disp = (int32)fetch_32();
1.1       root     2920:        } else if (disp == 0) {
                   2921:                // BSR.W <label>
1.1.1.5 ! root     2922:                disp = (int32)(int16)fetch_16();
1.1       root     2923:        }
                   2924:        // ページフォルトに備えて保存する
1.1.1.5 ! root     2925:        save_reg_pd(7);
        !          2926:        push_32(reg.pc);
        !          2927:        Jump(origin + disp);
1.1       root     2928: }
                   2929: 
1.1.1.5 ! root     2930: // %0110_cccc00_000000 Bcc.W <label>
        !          2931: // %0110_ccccnn_nnnnnn Bcc.B <label>
        !          2932: // %0110_cccc11_111111 Bcc.L <label>
1.1       root     2933: OP_DEF(bcc)
                   2934: {
1.1.1.5 ! root     2935:        // ブランチするかどうかでサイクルが変わるので先に条件を調べる
        !          2936:        uint cond = (ir >> 8) & 0x0f;
        !          2937:        if (CCR.Cond(cond)) {
        !          2938:                // Bcc (taken)
        !          2939:                ops_bra();
        !          2940:        } else {
        !          2941:                int32 disp = (int32)(int8)(ir & 0xff);
        !          2942:                if (disp == -1) {
        !          2943:                        // Bcc.L (not taken)
        !          2944:                        CYCLE(8);
        !          2945:                        fetch_32();
        !          2946:                } else if (disp == 0) {
        !          2947:                        // Bcc.W (not taken)
        !          2948:                        CYCLE(6);
        !          2949:                        fetch_16();
        !          2950:                } else {
        !          2951:                        // Bcc.B (not taken)
        !          2952:                        CYCLE(4);
        !          2953:                }
        !          2954:        }
1.1       root     2955: }
                   2956: 
                   2957: // %0111_xxx0nn_nnnnnn MOVEQ.L #<imm>,Dx
                   2958: OP_DEF(moveq)
                   2959: {
                   2960:        CYCLE(2);
1.1.1.5 ! root     2961:        RegDX = (int32)(int8)(ir & 0xff);
        !          2962:        ACC.move_32(RegDX);
1.1       root     2963: }
                   2964: 
                   2965: // %1000_xxx000_mmmrrr OR.B <ea>,Dx
                   2966: OP_DEF(or_b_ea_dn)
                   2967: {
1.1.1.5 ! root     2968:        uint n = ir & 0x3f;
1.1       root     2969: 
                   2970:        CYCLE(2);
                   2971:        int x = RegIRX;
                   2972:        if (n < 8) {
                   2973:                // OR.B Dn,Dx
1.1.1.5 ! root     2974:                uint32 data = (reg.D[x] | reg.D[n]) & 0xff;
        !          2975:                ACC.move_8(data);
        !          2976:                reg.D[x] = (reg.D[x] & 0xffffff00) | data;
1.1       root     2977:        } else {
                   2978:                // OR.B <ea>,Dx
1.1.1.5 ! root     2979:                uint32 src = fea_data_8();
        !          2980:                uint32 data = (reg.D[x] | src) & 0xff;
        !          2981:                ACC.move_8(data);
        !          2982:                reg.D[x] = (reg.D[x] & 0xffffff00) | data;
1.1       root     2983:        }
                   2984: }
                   2985: 
                   2986: // %1000_xxx001_mmmrrr OR.W <ea>,Dx
                   2987: OP_DEF(or_w_ea_dn)
                   2988: {
1.1.1.5 ! root     2989:        uint n = ir & 0x3f;
1.1       root     2990: 
                   2991:        CYCLE(2);
                   2992:        int x = RegIRX;
                   2993:        if (n < 8) {
                   2994:                // OR.W Dn,Dx
1.1.1.5 ! root     2995:                uint32 data = (reg.D[x] | reg.D[n]) & 0xffff;
        !          2996:                ACC.move_16(data);
        !          2997:                reg.D[x] = (reg.D[x] & 0xffff0000) | data;
1.1       root     2998:        } else {
                   2999:                // OR.W <ea>,Dx
1.1.1.5 ! root     3000:                uint32 src = fea_data_16();
        !          3001:                uint32 data = (reg.D[x] | src) & 0xffff;
        !          3002:                ACC.move_16(data);
        !          3003:                reg.D[x] = (reg.D[x] & 0xffff0000) | data;
1.1       root     3004:        }
                   3005: }
                   3006: 
                   3007: // %1000_xxx010_mmmrrr OR.L <ea>,Dx
                   3008: OP_DEF(or_l_ea_dn)
                   3009: {
1.1.1.5 ! root     3010:        uint n = ir & 0x3f;
1.1       root     3011: 
                   3012:        CYCLE(2);
                   3013:        int x = RegIRX;
                   3014:        if (n < 8) {
                   3015:                // OR.L Dn,Dx
1.1.1.5 ! root     3016:                reg.D[x] |= reg.D[n];
        !          3017:                ACC.move_32(reg.D[x]);
1.1       root     3018:        } else {
                   3019:                // OR.L <ea>,Dx
1.1.1.5 ! root     3020:                uint32 src = fea_data_32();
        !          3021:                uint32 data = reg.D[x] | src;
        !          3022:                ACC.move_32(data);
        !          3023:                reg.D[x] = data;
1.1       root     3024:        }
                   3025: }
                   3026: 
                   3027: // %1000_xxx011_mmmrrr DIVU.W <ea>,Dx
                   3028: OP_DEF(divu_w)
                   3029: {
                   3030:        CYCLE(44);      // XXX これは本当は最大値だけど
1.1.1.5 ! root     3031: 
        !          3032:        uint16 src = fea_data_16();
1.1       root     3033:        uint32 dst = RegDX;
1.1.1.5 ! root     3034: 
        !          3035:        if (src == 0) {
        !          3036:                // ゼロ除算の場合、
        !          3037:                // X は変化しない
        !          3038:                // C は常にクリア
        !          3039:                // N,Z,V は未定義
        !          3040:                CCR.SetC(false);
        !          3041:                Exception(M68K::EXCEP_ZERODIV);
        !          3042:                return;
1.1       root     3043:        }
1.1.1.5 ! root     3044: 
        !          3045:        uint32 quo = dst / src;
        !          3046:        uint32 rem = dst % src;
        !          3047:        if (quo > 0xffff) {
        !          3048:                // オーバーフローの場合、
        !          3049:                // X は変化しない
        !          3050:                // N,Z は未定義
        !          3051:                // V はセット
        !          3052:                // C は常にクリア
        !          3053:                CCR.SetV(true);
        !          3054:                CCR.SetC(false);
        !          3055:                return;
        !          3056:        }
        !          3057: 
        !          3058:        // 正常の場合、
        !          3059:        // X は変化しない
        !          3060:        // V, C はクリア
        !          3061:        // N, Z は quo の結果。
        !          3062:        RegDX = (rem << 16) | quo;
        !          3063:        ACC.move_16(quo);
1.1       root     3064: }
                   3065: 
                   3066: // %1000_xxx100_000yyy SBCD.B Dy,Dx
                   3067: // %1000_xxx100_001yyy SBCD.B -(Ay),-(Ax)
                   3068: // %1000_xxx100_mmmrrr OR.B Dx,<ea>
                   3069: OP_DEF(or_b_dn_ea)
                   3070: {
1.1.1.5 ! root     3071:        uint n = ir & 0x3f;
1.1       root     3072: 
                   3073:        if (n < 8) {
                   3074:                // SBCD.B Dy,Dx
                   3075:                CYCLE(4);
                   3076:                uint32 src = RegDY & 0xff;
                   3077:                uint32 dst = RegDX & 0xff;
1.1.1.5 ! root     3078:                dst = ACC.sbcd_8(src, dst);
1.1       root     3079:                RegDX &= 0xffffff00;
                   3080:                RegDX |= dst;
                   3081:        } else if (n < 16) {
                   3082:                // SBCD.B -(Ay),-(Ax)
                   3083:                CYCLE2(13, 14);
1.1.1.5 ! root     3084:                uint32 srcea = internal_ea_anpd_8(RegIRY);
        !          3085:                uint32 dstea = internal_ea_anpd_8(RegIRX);
        !          3086:                uint32 src = read_8(srcea);
        !          3087:                uint32 dst = read_8(dstea);
        !          3088:                dst = ACC.sbcd_8(src, dst);
        !          3089:                write_8(dstea, dst);
1.1       root     3090:        } else {
                   3091:                // OR.B Dx,<ea>
                   3092:                CYCLE2(3, 4);
1.1.1.5 ! root     3093:                uint32 ea = cea_data_8();
        !          3094:                uint8 data = read_8(ea);
1.1       root     3095:                data |= RegDX;
1.1.1.5 ! root     3096:                ACC.move_8(data);
        !          3097:                write_8(ea, data);
1.1       root     3098:        }
                   3099: }
                   3100: 
                   3101: // %1000_xxx101_000yyy PACK Dy,Dx,#<imm>
                   3102: // %1000_xxx101_001yyy PACK -(Ay),-(Ax),#<imm>
                   3103: // %1000_xxx101_mmmrrr OR.W Dx,<ea>
                   3104: OP_DEF(or_w_dn_ea)
                   3105: {
1.1.1.5 ! root     3106:        uint n = ir & 0x3f;
1.1       root     3107: 
                   3108:        if (n < 8) {
                   3109:                // PACK Dy,Dx,#<imm>
                   3110:                CYCLE(6);
1.1.1.5 ! root     3111:                uint32 imm = fetch_16();
1.1       root     3112:                uint32 src = RegDY + imm;
                   3113:                RegDX = (RegDX & 0xffffff00) | ((src >> 4) & 0x00f0) | (src & 0x000f);
                   3114:        } else if (n < 16) {
                   3115:                // PACK -(Ay),-(Ax),#<imm>
                   3116:                CYCLE(11);
1.1.1.5 ! root     3117:                uint32 imm = fetch_16();
1.1       root     3118:                uint32 srcea;
                   3119:                uint32 src;
                   3120:                // -(Ay) を2回行う
1.1.1.5 ! root     3121:                srcea = internal_ea_anpd_8(RegIRY);
        !          3122:                src = read_8(srcea);
        !          3123:                srcea = internal_ea_anpd_8(RegIRY);
        !          3124:                src |= (read_8(srcea) << 8);
1.1       root     3125:                src += imm;
                   3126:                uint32 dst = ((src >> 4) & 0x00f0) | (src & 0x000f);
1.1.1.5 ! root     3127:                uint32 dstea = internal_ea_anpd_8(RegIRX);
        !          3128:                write_8(dstea, dst);
1.1       root     3129:        } else {
                   3130:                // OR.W Dx,<ea>
                   3131:                CYCLE2(3, 4);
1.1.1.5 ! root     3132:                uint32 ea = cea_data_16();
        !          3133:                uint16 data = read_16(ea);
1.1       root     3134:                data |= RegDX;
1.1.1.5 ! root     3135:                ACC.move_16(data);
        !          3136:                write_16(ea, data);
1.1       root     3137:        }
                   3138: }
                   3139: 
                   3140: // %1000_xxx110_000yyy UNPK Dy,Dx,#<imm>
                   3141: // %1000_xxx110_001yyy UNPK -(Ay),-(Ax),#<imm>
                   3142: // %1000_xxx110_mmmrrr OR.L Dx,<ea>
                   3143: OP_DEF(or_l_dn_ea)
                   3144: {
1.1.1.5 ! root     3145:        uint n = ir & 0x3f;
1.1       root     3146: 
                   3147:        if (n < 8) {
                   3148:                // UNPK Dy,Dx,#<imm>
                   3149:                CYCLE(8);
1.1.1.5 ! root     3150:                uint32 imm = fetch_16();
1.1       root     3151:                uint16 src = RegDY;
                   3152:                src = ((src & 0x00f0) << 4) | (src & 0x000f);
                   3153:                src += imm;
                   3154:                RegDX = (RegDX & 0xffff0000) | src;
                   3155:        } else if (n < 16) {
                   3156:                // UNPK -(Ay),-(Ax),#<imm>
                   3157:                CYCLE(11);
1.1.1.5 ! root     3158:                uint32 imm = fetch_16();
        !          3159:                uint32 srcea = internal_ea_anpd_8(RegIRY);
        !          3160:                uint16 src = read_8(srcea);
1.1       root     3161:                src = ((src & 0x00f0) << 4) | (src & 0x000f);
                   3162:                src += imm;
                   3163:                // -(Ax) を2回行う
                   3164:                uint32 dstea;
1.1.1.5 ! root     3165:                dstea = internal_ea_anpd_8(RegIRX);
        !          3166:                write_8(dstea, (src & 0xff));
        !          3167:                dstea = internal_ea_anpd_8(RegIRX);
        !          3168:                write_8(dstea, src >> 8);
1.1       root     3169:        } else {
                   3170:                // OR.L Dx,<ea>
                   3171:                CYCLE2(3, 4);
1.1.1.5 ! root     3172:                uint32 ea = cea_data_32();
        !          3173:                uint32 data = read_32(ea);
1.1       root     3174:                data |= RegDX;
1.1.1.5 ! root     3175:                ACC.move_32(data);
        !          3176:                write_32(ea, data);
1.1       root     3177:        }
                   3178: }
                   3179: 
                   3180: // %1000_xxx111_mmmrrr DIVS.W <ea>,Dx
                   3181: OP_DEF(divs_w)
                   3182: {
                   3183:        CYCLE(56);      // XXX これは本当は最大値だけど
1.1.1.5 ! root     3184: 
        !          3185:        uint16 src = fea_data_16();
1.1       root     3186:        uint32 dst = RegDX;
1.1.1.5 ! root     3187: 
        !          3188:        if (src == 0) {
        !          3189:                // ゼロ除算の場合、
        !          3190:                // X は変化しない
        !          3191:                // C は常にクリア
        !          3192:                // N,Z,V は未定義
        !          3193:                CCR.SetC(false);
        !          3194:                Exception(M68K::EXCEP_ZERODIV);
        !          3195:                return;
        !          3196:        }
        !          3197: 
        !          3198:        // ホストでオーバーフローが起きるのはこのケースのみ
        !          3199:        if (dst == 0x80000000 && src == 0xffff) {
        !          3200:                // オーバーフローの場合、
        !          3201:                // X は変化しない
        !          3202:                // N,Z は未定義
        !          3203:                // V はセット
        !          3204:                // C は常にクリア
        !          3205:                CCR.SetV(true);
        !          3206:                CCR.SetC(false);
        !          3207:                return;
1.1       root     3208:        }
1.1.1.5 ! root     3209: 
        !          3210:        int32 squo = (int32)dst / (int32)(int16)src;
        !          3211:        int32 srem = (int32)dst % (int32)(int16)src;
        !          3212:        if ((int16)squo != squo) {
        !          3213:                // オーバーフローの場合
        !          3214:                CCR.SetV(true);
        !          3215:                CCR.SetC(false);
        !          3216:                return;
        !          3217:        }
        !          3218:        // 正常の場合、
        !          3219:        // X は変化しない
        !          3220:        // V, C はクリア
        !          3221:        // N, Z は quo の結果。
        !          3222:        uint32 quo = (uint32)squo & 0xffff;
        !          3223:        uint32 rem = (uint32)srem & 0xffff;
        !          3224:        RegDX = (rem << 16) | quo;
        !          3225:        ACC.move_16(quo);
1.1       root     3226: }
                   3227: 
                   3228: // %1001_xxx000_mmmrrr SUB.B <ea>,Dx
                   3229: OP_DEF(sub_b_ea_dn)
                   3230: {
                   3231:        CYCLE(2);
1.1.1.5 ! root     3232:        uint32 src = fea_all_8();
        !          3233:        uint32 data = ACC.sub_8(src, RegDX & 0xff);
1.1       root     3234:        RegDX = (RegDX & 0xffffff00) | data;
                   3235: }
                   3236: 
                   3237: // %1001_xxx001_mmmrrr SUB.W <ea>,Dx
                   3238: OP_DEF(sub_w_ea_dn)
                   3239: {
                   3240:        CYCLE(2);
1.1.1.5 ! root     3241:        uint32 src = fea_all_16();
        !          3242:        uint32 data = ACC.sub_16(src, RegDX & 0xffff);
1.1       root     3243:        RegDX = (RegDX & 0xffff0000) | data;
                   3244: }
                   3245: 
                   3246: // %1001_xxx010_mmmrrr SUB.L <ea>,Dx
                   3247: OP_DEF(sub_l_ea_dn)
                   3248: {
                   3249:        CYCLE(2);
1.1.1.5 ! root     3250:        uint32 src = fea_all_32();
        !          3251:        RegDX = ACC.sub_32(src, RegDX);
1.1       root     3252: }
                   3253: 
                   3254: // %1001_xxx011_mmmrrr SUBA.W <ea>,Ax
                   3255: OP_DEF(suba_w)
                   3256: {
                   3257:        CYCLE(4);
1.1.1.5 ! root     3258:        uint32 src = (int32)(int16)fea_all_16();
1.1       root     3259:        RegAX -= src;
                   3260: }
                   3261: 
                   3262: // %1001_xxx100_000yyy SUBX.B Dy,Dx
                   3263: // %1001_xxx100_001yyy SUBX.B -(Ay),-(Ax)
                   3264: // %1001_xxx100_mmmrrr SUB.B Dx,<ea>
                   3265: OP_DEF(sub_b_dn_ea)
                   3266: {
1.1.1.5 ! root     3267:        uint n = ir & 0x3f;
1.1       root     3268: 
                   3269:        if (n < 8) {
                   3270:                // SUBX.B Dy,Dx
                   3271:                CYCLE(2);
                   3272:                uint32 src = RegDY & 0xff;
                   3273:                uint32 dst = RegDX & 0xff;
1.1.1.5 ! root     3274:                dst = ACC.subx_8(src, dst);
1.1       root     3275:                RegDX = (RegDX & 0xffffff00) | dst;
                   3276:        } else if (n < 16) {
                   3277:                // SUBX.B -(Ay),-(Ax)
                   3278:                CYCLE2(9, 10);
1.1.1.5 ! root     3279:                uint32 srcea = internal_ea_anpd_8(RegIRY);
        !          3280:                uint32 dstea = internal_ea_anpd_8(RegIRX);
        !          3281:                uint32 src = read_8(srcea);
        !          3282:                uint32 dst = read_8(dstea);
        !          3283:                dst = ACC.subx_8(src, dst);
        !          3284:                write_8(dstea, dst);
1.1       root     3285:        } else {
                   3286:                // SUB.B Dx,<ea>
                   3287:                CYCLE2(3, 4);
1.1.1.5 ! root     3288:                uint32 ea = cea_data_8();
        !          3289:                uint32 data = read_8(ea);
        !          3290:                data = ACC.sub_8(RegDX & 0xff, data);
        !          3291:                write_8(ea, data);
1.1       root     3292:        }
                   3293: }
                   3294: 
                   3295: // %1001_xxx101_000yyy SUBX.W Dy,Dx
                   3296: // %1001_xxx101_001yyy SUBX.W -(Ay),-(Ax)
                   3297: // %1001_xxx101_mmmrrr SUB.W Dx,<ea>
                   3298: OP_DEF(sub_w_dn_ea)
                   3299: {
1.1.1.5 ! root     3300:        uint n = ir & 0x3f;
1.1       root     3301: 
                   3302:        if (n < 8) {
                   3303:                // SUBX.W Dy,Dx
                   3304:                CYCLE(2);
                   3305:                uint32 src = RegDY & 0xffff;
                   3306:                uint32 dst = RegDX & 0xffff;
1.1.1.5 ! root     3307:                dst = ACC.subx_16(src, dst);
1.1       root     3308:                RegDX = (RegDX & 0xffff0000) | dst;
                   3309:        } else if (n < 16) {
                   3310:                // SUBX.W -(Ay),-(Ax)
                   3311:                CYCLE2(9, 10);
1.1.1.5 ! root     3312:                uint32 srcea = internal_ea_anpd_16(RegIRY);
        !          3313:                uint32 dstea = internal_ea_anpd_16(RegIRX);
        !          3314:                uint32 src = read_16(srcea);
        !          3315:                uint32 dst = read_16(dstea);
        !          3316:                dst = ACC.subx_16(src, dst);
        !          3317:                write_16(dstea, dst);
1.1       root     3318:        } else {
                   3319:                // SUB.W Dx,<ea>
                   3320:                CYCLE2(3, 4);
1.1.1.5 ! root     3321:                uint32 ea = cea_data_16();
        !          3322:                uint32 data = read_16(ea);
        !          3323:                data = ACC.sub_16(RegDX & 0xffff, data);
        !          3324:                write_16(ea, data);
1.1       root     3325:        }
                   3326: }
                   3327: 
                   3328: // %1001_xxx110_000yyy SUBX.L Dy,Dx
                   3329: // %1001_xxx110_001yyy SUBX.L -(Ay),-(Ax)
                   3330: // %1001_xxx110_mmmrrr SUB.L Dx,<ea>
                   3331: OP_DEF(sub_l_dn_ea)
                   3332: {
1.1.1.5 ! root     3333:        uint n = ir & 0x3f;
1.1       root     3334: 
                   3335:        if (n < 8) {
                   3336:                // SUBX.L Dy,Dx
                   3337:                CYCLE(2);
                   3338:                uint32 src = RegDY;
                   3339:                uint32 dst = RegDX;
1.1.1.5 ! root     3340:                RegDX = ACC.subx_32(src, dst);
1.1       root     3341:        } else if (n < 16) {
                   3342:                // SUBX.L -(Ay),-(Ax)
                   3343:                CYCLE2(9, 10);
1.1.1.5 ! root     3344:                uint32 srcea = internal_ea_anpd_32(RegIRY);
        !          3345:                uint32 dstea = internal_ea_anpd_32(RegIRX);
        !          3346:                uint32 src = read_32(srcea);
        !          3347:                uint32 dst = read_32(dstea);
        !          3348:                dst = ACC.subx_32(src, dst);
        !          3349:                write_32(dstea, dst);
1.1       root     3350:        } else {
                   3351:                // SUB.L Dx,<ea>
                   3352:                CYCLE2(3, 4);
1.1.1.5 ! root     3353:                uint32 ea = cea_data_32();
        !          3354:                uint32 data = read_32(ea);
        !          3355:                data = ACC.sub_32(RegDX, data);
        !          3356:                write_32(ea, data);
1.1       root     3357:        }
                   3358: }
                   3359: 
                   3360: // %1001_xxx111_mmmrrr SUBA.L <ea>,Ax
                   3361: OP_DEF(suba_l)
                   3362: {
                   3363:        CYCLE(2);
1.1.1.5 ! root     3364:        uint32 src = fea_all_32();
1.1       root     3365:        RegAX -= src;
                   3366: }
                   3367: 
                   3368: // %1010_nnnnnn_nnnnnn A-Line
                   3369: OP_DEF(aline)
                   3370: {
1.1.1.5 ! root     3371:        if (aline_callback) {
        !          3372:                if (aline_callback(this, aline_arg)) {
1.1       root     3373:                        return;
                   3374:                }
                   3375:        }
                   3376:        // A系列命令例外
1.1.1.5 ! root     3377:        Exception(M68K::EXCEP_ALINE);
1.1       root     3378: }
                   3379: 
                   3380: // %1011_xxx000_mmmrrr CMP.B <ea>,Dx
                   3381: OP_DEF(cmp_b)
                   3382: {
                   3383:        CYCLE(2);
1.1.1.5 ! root     3384:        uint32 src = fea_all_8();
1.1       root     3385:        uint32 dst = RegDX & 0xff;
1.1.1.5 ! root     3386:        ACC.cmp_8(src, dst);
1.1       root     3387: }
                   3388: 
                   3389: // %1011_xxx001_mmmrrr CMP.W <ea>,Dx
                   3390: OP_DEF(cmp_w)
                   3391: {
                   3392:        CYCLE(2);
1.1.1.5 ! root     3393:        uint32 src = fea_all_16();
1.1       root     3394:        uint32 dst = RegDX & 0xffff;
1.1.1.5 ! root     3395:        ACC.cmp_16(src, dst);
1.1       root     3396: }
                   3397: 
                   3398: // %1011_xxx010_mmmrrr CMP.L <ea>,Dx
                   3399: OP_DEF(cmp_l)
                   3400: {
                   3401:        CYCLE(2);
1.1.1.5 ! root     3402:        uint32 src = fea_all_32();
        !          3403:        ACC.cmp_32(src, RegDX);
1.1       root     3404: }
                   3405: 
                   3406: // %1011_xxx011_mmmrrr CMPA.W <ea>,Ax
                   3407: OP_DEF(cmpa_w)
                   3408: {
                   3409:        CYCLE(4);
1.1.1.5 ! root     3410:        uint32 src = (uint32)(int32)(int16)fea_all_16();
        !          3411:        ACC.cmp_32(src, RegAX);
1.1       root     3412: }
                   3413: 
                   3414: // %1011_xxx100_mmmrrr EOR.B Dx,<ea>
                   3415: // %1011_xxx100_001yyy CMPM.B (Ay)+,(Ax)+
                   3416: OP_DEF(eor_b)
                   3417: {
1.1.1.5 ! root     3418:        uint n = ir & 0x3f;
1.1       root     3419: 
                   3420:        if (n < 8) {
                   3421:                // EOR.B Dx,Dy
                   3422:                CYCLE(2);
1.1.1.5 ! root     3423:                uint32 data = (reg.D[n] ^ RegDX) & 0xff;
        !          3424:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
        !          3425:                ACC.move_8(data);
1.1       root     3426:        } else if (n < 16) {
                   3427:                // CMPM.B (Ay)+,(Ax)+
                   3428:                CYCLE(8);
1.1.1.5 ! root     3429:                uint32 srcea = internal_ea_anpi_8(RegIRY);
        !          3430:                uint32 dstea = internal_ea_anpi_8(RegIRX);
        !          3431:                uint32 src = read_8(srcea);
        !          3432:                uint32 dst = read_8(dstea);
        !          3433:                ACC.cmp_8(src, dst);
1.1       root     3434:        } else {
                   3435:                // EOR.B Dx,<ea>
                   3436:                CYCLE2(3, 4);
1.1.1.5 ! root     3437:                uint32 ea = cea_data_8();
        !          3438:                uint32 data = read_8(ea);
1.1       root     3439:                data ^= (RegDX & 0xff);
1.1.1.5 ! root     3440:                write_8(ea, data);
        !          3441:                ACC.move_8(data);
1.1       root     3442:        }
                   3443: }
                   3444: 
                   3445: // %1011_xxx101_mmmrrr EOR.W Dx,<ea>
                   3446: // %1011_xxx101_001yyy CMPM.W (Ay)+,(Ax)+
                   3447: OP_DEF(eor_w)
                   3448: {
1.1.1.5 ! root     3449:        uint n = ir & 0x3f;
1.1       root     3450: 
                   3451:        if (n < 8) {
                   3452:                // EOR.W Dx,Dy
                   3453:                CYCLE(2);
1.1.1.5 ! root     3454:                uint32 data = (reg.D[n] ^ RegDX) & 0xffff;
        !          3455:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
        !          3456:                ACC.move_16(data);
1.1       root     3457:        } else if (n < 16) {
                   3458:                // CMPM.W (Ay)+,(Ax)+
                   3459:                CYCLE(8);
1.1.1.5 ! root     3460:                uint32 srcea = internal_ea_anpi_16(RegIRY);
        !          3461:                uint32 dstea = internal_ea_anpi_16(RegIRX);
        !          3462:                uint32 src = read_16(srcea);
        !          3463:                uint32 dst = read_16(dstea);
        !          3464:                ACC.cmp_16(src, dst);
1.1       root     3465:        } else {
                   3466:                // EOR.W Dx,<ea>
                   3467:                CYCLE2(3, 4);
1.1.1.5 ! root     3468:                uint32 ea = cea_data_16();
        !          3469:                uint32 data = read_16(ea);
1.1       root     3470:                data ^= (RegDX & 0xffff);
1.1.1.5 ! root     3471:                write_16(ea, data);
        !          3472:                ACC.move_16(data);
1.1       root     3473:        }
                   3474: }
                   3475: 
                   3476: // %1011_xxx110_mmmrrr EOR.L Dx,<ea>
                   3477: // %1011_xxx110_001yyy CMPM.L (Ay)+,(Ax)+
                   3478: OP_DEF(eor_l)
                   3479: {
1.1.1.5 ! root     3480:        uint n = ir & 0x3f;
1.1       root     3481: 
                   3482:        if (n < 8) {
                   3483:                CYCLE(2);
                   3484:                // EOR.L Dx,Dy
1.1.1.5 ! root     3485:                reg.D[n] ^= RegDX;
        !          3486:                ACC.move_32(reg.D[n]);
1.1       root     3487:        } else if (n < 16) {
                   3488:                // CMPM.L (Ay)+,(Ax)+
                   3489:                CYCLE(8);
1.1.1.5 ! root     3490:                uint32 srcea = internal_ea_anpi_32(RegIRY);
        !          3491:                uint32 dstea = internal_ea_anpi_32(RegIRX);
        !          3492:                uint32 src = read_32(srcea);
        !          3493:                uint32 dst = read_32(dstea);
        !          3494:                ACC.cmp_32(src, dst);
1.1       root     3495:        } else {
                   3496:                // EOR.L Dx,<ea>
                   3497:                CYCLE2(3, 4);
1.1.1.5 ! root     3498:                uint32 ea = cea_data_32();
        !          3499:                uint32 data = read_32(ea);
1.1       root     3500:                data ^= RegDX;
1.1.1.5 ! root     3501:                write_32(ea, data);
        !          3502:                ACC.move_32(data);
1.1       root     3503:        }
                   3504: }
                   3505: 
                   3506: // %1011_xxx111_mmmrrr CMPA.L <ea>,Ax
                   3507: OP_DEF(cmpa_l)
                   3508: {
                   3509:        CYCLE(4);
1.1.1.5 ! root     3510:        uint32 src = fea_all_32();
        !          3511:        ACC.cmp_32(src, RegAX);
1.1       root     3512: }
                   3513: 
                   3514: // %1100_xxx000_mmmrrr AND.B <ea>,Dx
                   3515: OP_DEF(and_b_ea_dn)
                   3516: {
                   3517:        CYCLE(2);
1.1.1.5 ! root     3518:        uint32 src = fea_data_8();
1.1       root     3519:        uint32 dst = (RegDX & 0x000000ff) & src;
1.1.1.5 ! root     3520:        ACC.move_8(dst);
1.1       root     3521:        RegDX = (RegDX & 0xffffff00) | dst;
                   3522: }
                   3523: 
                   3524: // %1100_xxx001_mmmrrr AND.W <ea>,Dx
                   3525: OP_DEF(and_w_ea_dn)
                   3526: {
                   3527:        CYCLE(2);
1.1.1.5 ! root     3528:        uint32 src = fea_data_16();
1.1       root     3529:        uint32 dst = (RegDX & 0x0000ffff) & src;
1.1.1.5 ! root     3530:        ACC.move_16(dst);
1.1       root     3531:        RegDX = (RegDX & 0xffff0000) | dst;
                   3532: }
                   3533: 
                   3534: // %1100_xxx010_mmmrrr AND.L <ea>,Dx
                   3535: OP_DEF(and_l_ea_dn)
                   3536: {
                   3537:        CYCLE(2);
1.1.1.5 ! root     3538:        uint32 src = fea_data_32();
1.1       root     3539:        RegDX = RegDX & src;
1.1.1.5 ! root     3540:        ACC.move_32(RegDX);
1.1       root     3541: }
                   3542: 
                   3543: // %1100_xxx011_mmmrrr MULU.W <ea>,Dx
                   3544: OP_DEF(mulu_w)
                   3545: {
                   3546:        CYCLE(28);      // 実際にはこれは最大値
1.1.1.5 ! root     3547:        uint32 src = fea_data_16();
1.1       root     3548:        uint32 dst = RegDX & 0xffff;
1.1.1.5 ! root     3549:        RegDX = ACC.mulu_16(src, dst);
1.1       root     3550: }
                   3551: 
                   3552: // %1100_xxx100_000yyy ABCD.B Dy,Dx
                   3553: // %1100_xxx100_001yyy ABCD.B -(Ay),-(Ax)
                   3554: // %1100_xxx100_mmmrrr AND.B Dx,<ea>
                   3555: OP_DEF(and_b_dn_ea)
                   3556: {
1.1.1.5 ! root     3557:        uint n = ir & 0x3f;
1.1       root     3558: 
                   3559:        if (n < 8) {
                   3560:                // ABCD.B Dy,Dx
                   3561:                CYCLE(4);
                   3562:                uint32 src = RegDY & 0xff;
                   3563:                uint32 dst = RegDX & 0xff;
1.1.1.5 ! root     3564:                dst = ACC.abcd_8(src, dst);
1.1       root     3565:                RegDX &= 0xffffff00;
                   3566:                RegDX |= dst;
                   3567:                return;
                   3568:        } else if (n < 16) {
                   3569:                // ABCD.B -(Ay),-(Ax)
                   3570:                CYCLE2(13, 14);
1.1.1.5 ! root     3571:                uint32 srcea = internal_ea_anpd_8(RegIRY);
        !          3572:                uint32 dstea = internal_ea_anpd_8(RegIRX);
        !          3573:                uint32 src = read_8(srcea);
        !          3574:                uint32 dst = read_8(dstea);
        !          3575:                dst = ACC.abcd_8(src, dst);
        !          3576:                write_8(dstea, dst);
1.1       root     3577:                return;
                   3578:        } else {
                   3579:                // AND.B Dx,<ea>
                   3580:                CYCLE2(3, 4);
1.1.1.5 ! root     3581:                uint32 ea = cea_data_8();
        !          3582:                uint32 dst = read_8(ea);
1.1       root     3583:                dst &= RegDX & 0xff;
1.1.1.5 ! root     3584:                ACC.move_8(dst);
        !          3585:                write_8(ea, dst);
1.1       root     3586:        }
                   3587: }
                   3588: 
                   3589: // %1100_xxx101_000yyy EXG.L Dx,Dy
                   3590: // %1100_xxx101_001yyy EXG.L Ax,Ay
                   3591: // %1100_xxx101_mmmrrr AND.W Dx,<ea>
                   3592: OP_DEF(and_w_dn_ea)
                   3593: {
1.1.1.5 ! root     3594:        uint n = ir & 0x3f;
1.1       root     3595: 
                   3596:        if (n < 8) {
                   3597:                // EXG.L Dx,Dy
                   3598:                CYCLE(4);
                   3599:                int x = RegIRX;
                   3600:                int y = n;
1.1.1.5 ! root     3601:                uint32 tmp = reg.D[x];
        !          3602:                reg.D[x] = reg.D[y];
        !          3603:                reg.D[y] = tmp;
1.1       root     3604:                return;
                   3605:        } else if (n < 16) {
                   3606:                // EXG.L Ax,Ay
                   3607:                // ここでは x は 0..7 で A(x)、y は 8..15 で R(y)
                   3608:                CYCLE(4);
                   3609:                int x = RegIRX;
                   3610:                int y = n;
1.1.1.5 ! root     3611:                uint32 tmp = reg.A[x];
        !          3612:                reg.A[x] = reg.R[y];
        !          3613:                reg.R[y] = tmp;
1.1       root     3614:                return;
                   3615:        } else {
                   3616:                // AND.W Dx,<ea>
                   3617:                CYCLE2(3, 4);
1.1.1.5 ! root     3618:                uint32 ea = cea_data_16();
        !          3619:                uint32 dst = read_16(ea);
1.1       root     3620:                dst &= RegDX & 0xffff;
1.1.1.5 ! root     3621:                ACC.move_16(dst);
        !          3622:                write_16(ea, dst);
1.1       root     3623:        }
                   3624: }
                   3625: 
                   3626: // %1100_xxx110_001yyy EXG.L Dx,Ay
                   3627: // %1100_xxx110_mmmrrr AND.L Dx,<ea>
                   3628: OP_DEF(and_l_dn_ea)
                   3629: {
1.1.1.5 ! root     3630:        uint n = ir & 0x3f;
1.1       root     3631: 
                   3632:        if (n < 8) {
1.1.1.5 ! root     3633:                op_illegal();
1.1       root     3634:                return;
                   3635:        } else if (n < 16) {
                   3636:                // EXG.L Dx,Ay
                   3637:                // ここでは x は 0..7 で D(x)、y は 8..15 で R(y)
                   3638:                CYCLE(4);
                   3639:                int x = RegIRX;
                   3640:                int y = n;
1.1.1.5 ! root     3641:                uint32 tmp = reg.D[x];
        !          3642:                reg.D[x] = reg.R[y];
        !          3643:                reg.R[y] = tmp;
1.1       root     3644:                return;
                   3645:        } else {
                   3646:                // AND.L Dx,<ea>
                   3647:                CYCLE2(3, 4);
1.1.1.5 ! root     3648:                uint32 ea = cea_data_32();
        !          3649:                uint32 dst = read_32(ea);
1.1       root     3650:                dst &= RegDX;
1.1.1.5 ! root     3651:                ACC.move_32(dst);
        !          3652:                write_32(ea, dst);
1.1       root     3653:        }
                   3654: }
                   3655: 
                   3656: // %1100_xxx111_mmmrrr MULS.W <ea>,Dx
                   3657: OP_DEF(muls_w)
                   3658: {
                   3659:        CYCLE(28);      // 実際にはこれは最大値
1.1.1.5 ! root     3660:        uint32 src = fea_data_16();
1.1       root     3661:        uint32 dst = RegDX & 0xffff;
1.1.1.5 ! root     3662:        RegDX = ACC.muls_16(src, dst);
1.1       root     3663: }
                   3664: 
                   3665: // %1101_xxx000_mmmrrr ADD.B <ea>,Dx
                   3666: OP_DEF(add_b_ea_dn)
                   3667: {
                   3668:        CYCLE(2);
1.1.1.5 ! root     3669:        uint32 src = fea_all_8();
        !          3670:        uint32 data = ACC.add_8(src, RegDX & 0xff);
1.1       root     3671:        RegDX = (RegDX & 0xffffff00) | data;
                   3672: }
                   3673: 
                   3674: // %1101_xxx001_mmmrrr ADD.W <ea>,Dx
                   3675: OP_DEF(add_w_ea_dn)
                   3676: {
                   3677:        CYCLE(2);
1.1.1.5 ! root     3678:        uint32 src = fea_all_16();
        !          3679:        uint32 data = ACC.add_16(src, RegDX & 0xffff);
1.1       root     3680:        RegDX = (RegDX & 0xffff0000) | data;
                   3681: }
                   3682: 
                   3683: // %1101_xxx010_mmmrrr ADD.L <ea>,Dx
                   3684: OP_DEF(add_l_ea_dn)
                   3685: {
                   3686:        CYCLE(2);
1.1.1.5 ! root     3687:        uint32 src = fea_all_32();
        !          3688:        RegDX = ACC.add_32(src, RegDX);
1.1       root     3689: }
                   3690: 
                   3691: // %1101_xxx011_mmmrrr ADDA.W <ea>,Ax
                   3692: OP_DEF(adda_w)
                   3693: {
                   3694:        CYCLE(4);
1.1.1.5 ! root     3695:        uint32 src = (int32)(int16)fea_all_16();
1.1       root     3696:        RegAX += src;
                   3697: }
                   3698: 
                   3699: // %1101_xxx100_000yyy ADDX.B Dy,Dx
                   3700: // %1101_xxx100_001yyy ADDX.B -(Ay),-(Ax)
                   3701: // %1101_xxx100_mmmrrr ADD.B Dx,<ea>
                   3702: OP_DEF(add_b_dn_ea)
                   3703: {
1.1.1.5 ! root     3704:        uint n = ir & 0x3f;
1.1       root     3705: 
                   3706:        if (n < 8) {
                   3707:                // ADDX.B Dy,Dx
                   3708:                CYCLE(2);
                   3709:                uint32 src = RegDY & 0xff;
                   3710:                uint32 dst = RegDX & 0xff;
1.1.1.5 ! root     3711:                dst = ACC.addx_8(src, dst);
1.1       root     3712:                RegDX = (RegDX & 0xffffff00) | dst;
                   3713:        } else if (n < 16) {
                   3714:                // ADDX.B -(Ay),-(Ax)
                   3715:                CYCLE2(9, 10);
1.1.1.5 ! root     3716:                uint32 srcea = internal_ea_anpd_8(RegIRY);
        !          3717:                uint32 dstea = internal_ea_anpd_8(RegIRX);
        !          3718:                uint32 src = read_8(srcea);
        !          3719:                uint32 dst = read_8(dstea);
        !          3720:                dst = ACC.addx_8(src, dst);
        !          3721:                write_8(dstea, dst);
1.1       root     3722:        } else {
                   3723:                // ADD.B Dx,<ea>
                   3724:                CYCLE2(3, 4);
1.1.1.5 ! root     3725:                uint32 ea = cea_data_8();
        !          3726:                uint32 data = read_8(ea);
        !          3727:                data = ACC.add_8(RegDX & 0xff, data);
        !          3728:                write_8(ea, data);
1.1       root     3729:        }
                   3730: }
                   3731: 
                   3732: // %1101_xxx101_000yyy ADDX.W Dy,Dx
                   3733: // %1101_xxx101_001yyy ADDX.W -(Ay),-(Ax)
                   3734: // %1101_xxx101_mmmrrr ADD.W Dx,<ea>
                   3735: OP_DEF(add_w_dn_ea)
                   3736: {
1.1.1.5 ! root     3737:        uint n = ir & 0x3f;
1.1       root     3738: 
                   3739:        if (n < 8) {
                   3740:                // ADDX.W Dy,Dx
                   3741:                CYCLE(2);
                   3742:                uint32 src = RegDY & 0xffff;
                   3743:                uint32 dst = RegDX & 0xffff;
1.1.1.5 ! root     3744:                dst = ACC.addx_16(src, dst);
1.1       root     3745:                RegDX = (RegDX & 0xffff0000) | dst;
                   3746:        } else if (n < 16) {
                   3747:                // ADDX.W -(Ay),-(Ax)
                   3748:                CYCLE2(9, 10);
1.1.1.5 ! root     3749:                uint32 srcea = internal_ea_anpd_16(RegIRY);
        !          3750:                uint32 dstea = internal_ea_anpd_16(RegIRX);
        !          3751:                uint32 src = read_16(srcea);
        !          3752:                uint32 dst = read_16(dstea);
        !          3753:                dst = ACC.addx_16(src, dst);
        !          3754:                write_16(dstea, dst);
1.1       root     3755:        } else {
                   3756:                // ADD.W Dx,<ea>
                   3757:                CYCLE2(3, 4);
1.1.1.5 ! root     3758:                uint32 ea = cea_data_16();
        !          3759:                uint32 data = read_16(ea);
        !          3760:                data = ACC.add_16(RegDX & 0xffff, data);
        !          3761:                write_16(ea, data);
1.1       root     3762:        }
                   3763: }
                   3764: 
                   3765: // %1101_xxx110_000yyy ADDX.L Dy,Dx
                   3766: // %1101_xxx110_001yyy ADDX.L -(Ay),-(Ax)
                   3767: // %1101_xxx110_mmmrrr ADD.L Dx,<ea>
                   3768: OP_DEF(add_l_dn_ea)
                   3769: {
1.1.1.5 ! root     3770:        uint n = ir & 0x3f;
1.1       root     3771: 
                   3772:        if (n < 8) {
                   3773:                // ADDX.L Dy,Dx
                   3774:                CYCLE(2);
                   3775:                uint32 src = RegDY;
                   3776:                uint32 dst = RegDX;
1.1.1.5 ! root     3777:                RegDX = ACC.addx_32(src, dst);
1.1       root     3778:        } else if (n < 16) {
                   3779:                // ADDX.L -(Ay),-(Ax)
                   3780:                CYCLE2(9, 10);
1.1.1.5 ! root     3781:                uint32 srcea = internal_ea_anpd_32(RegIRY);
        !          3782:                uint32 dstea = internal_ea_anpd_32(RegIRX);
        !          3783:                uint32 src = read_32(srcea);
        !          3784:                uint32 dst = read_32(dstea);
        !          3785:                dst = ACC.addx_32(src, dst);
        !          3786:                write_32(dstea, dst);
1.1       root     3787:        } else {
                   3788:                // ADD.L Dx,<ea>
                   3789:                CYCLE2(3, 4);
1.1.1.5 ! root     3790:                uint32 ea = cea_data_32();
        !          3791:                uint32 data = read_32(ea);
        !          3792:                data = ACC.add_32(RegDX, data);
        !          3793:                write_32(ea, data);
1.1       root     3794:        }
                   3795: }
                   3796: 
                   3797: // %1101_xxx111_mmmrrr ADDA.L <ea>,Ax
                   3798: OP_DEF(adda_l)
                   3799: {
                   3800:        CYCLE(2);
1.1.1.5 ! root     3801:        uint32 src = fea_all_32();
1.1       root     3802:        RegAX += src;
                   3803: }
                   3804: 
                   3805: // %1110_qqq000_000yyy ASR.B #qqq,Dy
                   3806: // %1110_qqq000_001yyy LSR.B #qqq,Dy
                   3807: // %1110_qqq000_010yyy ROXR.B #qqq,Dy
                   3808: // %1110_qqq000_011yyy ROR.B #qqq,Dy
                   3809: // %1110_xxx000_100yyy ASR.B Dx,Dy
                   3810: // %1110_xxx000_101yyy LSR.B Dx,Dy
                   3811: // %1110_xxx000_110yyy ROXR.B Dx,Dy
                   3812: // %1110_xxx000_111yyy ROR.B Dx,Dy
                   3813: OP_DEF(asr_b_imm)
                   3814: {
                   3815:        int count;
                   3816:        uint32 data;
1.1.1.5 ! root     3817:        switch (eamode(ir)) {
1.1       root     3818:         case 0:        // ASR.B #qqq,Dy
                   3819:                CYCLE(4);
                   3820:                count = RegIRX;
                   3821:                count = (count == 0) ? 8 : count;
                   3822:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3823:                data = ACC.asr_8(RegDY & 0xff, count);
1.1       root     3824:                RegDY = (RegDY & 0xffffff00) | data;
                   3825:                return;
                   3826:         case 1:        // LSR.B #qqq,Dy
                   3827:                CYCLE(4);
                   3828:                count = RegIRX;
                   3829:                count = (count == 0) ? 8 : count;
                   3830:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3831:                data = ACC.lsr_8(RegDY & 0xff, count);
1.1       root     3832:                RegDY = (RegDY & 0xffffff00) | data;
                   3833:                return;
                   3834:         case 2:        // ROXR.B #qqq,Dy
                   3835:                CYCLE(12);
                   3836:                count = RegIRX;
                   3837:                count = (count == 0) ? 8 : count;
                   3838:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3839:                data = ACC.roxr_8(RegDY & 0xff, count);
1.1       root     3840:                RegDY = (RegDY & 0xffffff00) | data;
                   3841:                return;
                   3842:         case 3:        // ROR.B #qqq,Dy
                   3843:                CYCLE(6);
                   3844:                count = RegIRX;
                   3845:                count = (count == 0) ? 8 : count;
                   3846:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3847:                data = ACC.ror_8(RegDY & 0xff, count);
1.1       root     3848:                RegDY = (RegDY & 0xffffff00) | data;
                   3849:                return;
                   3850:         case 4:        // ASR.B Dx,Dy
                   3851:                count = RegDX & 63;
                   3852:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   3853:                CYCLE(count <= 8 ? 6 : 10);
                   3854:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3855:                data = ACC.asr_8(RegDY & 0xff, count);
1.1       root     3856:                RegDY = (RegDY & 0xffffff00) | data;
                   3857:                return;
                   3858:         case 5:        // LSR.B Dx,Dy
                   3859:                count = RegDX & 63;
                   3860:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   3861:                CYCLE(count <= 8 ? 6 : 8);
                   3862:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3863:                data = ACC.lsr_8(RegDY & 0xff, count);
1.1       root     3864:                RegDY = (RegDY & 0xffffff00) | data;
                   3865:                return;
                   3866:         case 6:        // ROXR.B Dx,Dy
                   3867:                CYCLE(12);
                   3868:                count = RegDX & 63;
                   3869:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3870:                data = ACC.roxr_8(RegDY & 0xff, count);
1.1       root     3871:                RegDY = (RegDY & 0xffffff00) | data;
                   3872:                return;
                   3873:         case 7:        // ROR.B Dx,Dy
                   3874:                CYCLE(8);
                   3875:                count = RegDX & 63;
                   3876:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3877:                data = ACC.ror_8(RegDY & 0xff, count);
1.1       root     3878:                RegDY = (RegDY & 0xffffff00) | data;
                   3879:                return;
                   3880:        }
                   3881: }
                   3882: 
                   3883: // %1110_qqq001_000yyy ASR.W #qqq,Dy
                   3884: // %1110_qqq001_001yyy LSR.W #qqq,Dy
                   3885: // %1110_qqq001_010yyy ROXR.W #qqq,Dy
                   3886: // %1110_qqq001_011yyy ROR.W #qqq,Dy
                   3887: // %1110_xxx001_100yyy ASR.W Dx,Dy
                   3888: // %1110_xxx001_101yyy LSR.W Dx,Dy
                   3889: // %1110_xxx001_110yyy ROXR.W Dx,Dy
                   3890: // %1110_xxx001_111yyy ROR.W Dx,Dy
                   3891: OP_DEF(asr_w_imm)
                   3892: {
                   3893:        int count;
                   3894:        uint32 data;
1.1.1.5 ! root     3895:        switch (eamode(ir)) {
1.1       root     3896:         case 0:        // ASR.W #qqq,Dy
                   3897:                CYCLE(4);
                   3898:                count = RegIRX;
                   3899:                count = (count == 0) ? 8 : count;
                   3900:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3901:                data = ACC.asr_16(RegDY & 0xffff, count);
1.1       root     3902:                RegDY = (RegDY & 0xffff0000) | data;
                   3903:                return;
                   3904:         case 1:        // LSR.W #qqq,Dy
                   3905:                CYCLE(4);
                   3906:                count = RegIRX;
                   3907:                count = (count == 0) ? 8 : count;
                   3908:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3909:                data = ACC.lsr_16(RegDY & 0xffff, count);
1.1       root     3910:                RegDY = (RegDY & 0xffff0000) | data;
                   3911:                return;
                   3912:         case 2:        // ROXR.W #qqq,Dy
                   3913:                CYCLE(12);
                   3914:                count = RegIRX;
                   3915:                count = (count == 0) ? 8 : count;
                   3916:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3917:                data = ACC.roxr_16(RegDY & 0xffff, count);
1.1       root     3918:                RegDY = (RegDY & 0xffff0000) | data;
                   3919:                return;
                   3920:         case 3:        // ROR.W #qqq,Dy
                   3921:                CYCLE(6);
                   3922:                count = RegIRX;
                   3923:                count = (count == 0) ? 8 : count;
                   3924:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3925:                data = ACC.ror_16(RegDY & 0xffff, count);
1.1       root     3926:                RegDY = (RegDY & 0xffff0000) | data;
                   3927:                return;
                   3928:         case 4:        // ASR.W Dx,Dy
                   3929:                count = RegDX & 63;
                   3930:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   3931:                CYCLE(count <= 16 ? 6 : 10);
                   3932:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3933:                data = ACC.asr_16(RegDY & 0xffff, count);
1.1       root     3934:                RegDY = (RegDY & 0xffff0000) | data;
                   3935:                return;
                   3936:         case 5:        // LSR.W Dx,Dy
                   3937:                count = RegDX & 63;
                   3938:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   3939:                CYCLE(count <= 16 ? 6 : 8);
                   3940:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3941:                data = ACC.lsr_16(RegDY & 0xffff, count);
1.1       root     3942:                RegDY = (RegDY & 0xffff0000) | data;
                   3943:                return;
                   3944:         case 6:        // ROXR.W Dx,Dy
                   3945:                CYCLE(12);
                   3946:                count = RegDX & 63;
                   3947:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3948:                data = ACC.roxr_16(RegDY & 0xffff, count);
1.1       root     3949:                RegDY = (RegDY & 0xffff0000) | data;
                   3950:                return;
                   3951:         case 7:        // ROR.W Dx,Dy
                   3952:                CYCLE(8);
                   3953:                count = RegDX & 63;
                   3954:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     3955:                data = ACC.ror_16(RegDY & 0xffff, count);
1.1       root     3956:                RegDY = (RegDY & 0xffff0000) | data;
                   3957:                return;
                   3958:        }
                   3959: }
                   3960: 
                   3961: // %1110_qqq010_000yyy ASR.L #qqq,Dy
                   3962: // %1110_qqq010_001yyy LSR.L #qqq,Dy
                   3963: // %1110_qqq010_010yyy ROXR.L #qqq,Dy
                   3964: // %1110_qqq010_011yyy ROR.L #qqq,Dy
                   3965: // %1110_xxx010_100yyy ASR.L Dx,Dy
                   3966: // %1110_xxx010_101yyy LSR.L Dx,Dy
                   3967: // %1110_xxx010_110yyy ROXR.L Dx,Dy
                   3968: // %1110_xxx010_111yyy ROR.L Dx,Dy
                   3969: OP_DEF(asr_l_imm)
                   3970: {
                   3971:        int count;
1.1.1.5 ! root     3972:        switch (eamode(ir)) {
1.1       root     3973:         case 0:        // ASR.L #qqq,Dy
                   3974:                CYCLE(4);
                   3975:                count = RegIRX;
                   3976:                count = (count == 0) ? 8 : count;
                   3977:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3978:                RegDY = ACC.asr_32(RegDY, count);
1.1       root     3979:                return;
                   3980:         case 1:        // LSR.L #qqq,Dy
                   3981:                CYCLE(4);
                   3982:                count = RegIRX;
                   3983:                count = (count == 0) ? 8 : count;
                   3984:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3985:                RegDY = ACC.lsr_32(RegDY, count);
1.1       root     3986:                return;
                   3987:         case 2:        // ROXR.L #qqq,Dy
                   3988:                CYCLE(12);
                   3989:                count = RegIRX;
                   3990:                count = (count == 0) ? 8 : count;
                   3991:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3992:                RegDY = ACC.roxr_32(RegDY, count);
1.1       root     3993:                return;
                   3994:         case 3:        // ROR.L #qqq,Dy
                   3995:                CYCLE(6);
                   3996:                count = RegIRX;
                   3997:                count = (count == 0) ? 8 : count;
                   3998:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     3999:                RegDY = ACC.ror_32(RegDY, count);
1.1       root     4000:                return;
                   4001:         case 4:        // ASR.L Dx,Dy
                   4002:                count = RegDX & 63;
                   4003:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   4004:                CYCLE(count <= 32 ? 6 : 10);
                   4005:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4006:                RegDY = ACC.asr_32(RegDY, count);
1.1       root     4007:                return;
                   4008:         case 5:        // LSR.L Dx,Dy
                   4009:                count = RegDX & 63;
                   4010:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   4011:                CYCLE(count <= 32 ? 6 : 8);
                   4012:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4013:                RegDY = ACC.lsr_32(RegDY, count);
1.1       root     4014:                return;
                   4015:         case 6:        // ROXR.L Dx,Dy
                   4016:                CYCLE(12);
                   4017:                count = RegDX & 63;
                   4018:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4019:                RegDY = ACC.roxr_32(RegDY, count);
1.1       root     4020:                return;
                   4021:         case 7:        // ROR.L Dx,Dy
                   4022:                CYCLE(8);
                   4023:                count = RegDX & 63;
                   4024:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4025:                RegDY = ACC.ror_32(RegDY, count);
1.1       root     4026:                return;
                   4027:        }
                   4028: }
                   4029: 
                   4030: // %1110_000011_mmmrrr ASR.W <ea>
                   4031: OP_DEF(asr_w)
                   4032: {
                   4033:        CYCLE(4);
1.1.1.5 ! root     4034:        uint32 ea = cea_data_16();
        !          4035:        uint32 data = read_16(ea);
        !          4036:        data = ACC.asr_16(data, 1);
        !          4037:        write_16(ea, data);
1.1       root     4038: }
                   4039: 
                   4040: // %1110_qqq100_000yyy ASL.B #qqq,Dy
                   4041: // %1110_qqq100_001yyy LSL.B #qqq,Dy
                   4042: // %1110_qqq100_010yyy ROXL.B #qqq,Dy
                   4043: // %1110_qqq100_011yyy ROL.B #qqq,Dy
                   4044: // %1110_xxx100_100yyy ASL.B Dx,Dy
                   4045: // %1110_xxx100_101yyy LSL.B Dx,Dy
                   4046: // %1110_xxx100_110yyy ROXL.B Dx,Dy
                   4047: // %1110_xxx100_111yyy ROL.B Dx,Dy
                   4048: OP_DEF(asl_b_imm)
                   4049: {
                   4050:        int count;
                   4051:        uint32 data;
1.1.1.5 ! root     4052:        switch (eamode(ir)) {
1.1       root     4053:         case 0:        // ASL.B #qqq,Dy
                   4054:                CYCLE(6);
                   4055:                count = RegIRX;
                   4056:                count = (count == 0) ? 8 : count;
                   4057:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4058:                data = ACC.asl_8(RegDY & 0xff, count);
1.1       root     4059:                RegDY = (RegDY & 0xffffff00) | data;
                   4060:                return;
                   4061:         case 1:        // LSL.B #qqq,Dy
                   4062:                CYCLE(4);
                   4063:                count = RegIRX;
                   4064:                count = (count == 0) ? 8 : count;
                   4065:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4066:                data = ACC.lsl_8(RegDY & 0xff, count);
1.1       root     4067:                RegDY = (RegDY & 0xffffff00) | data;
                   4068:                return;
                   4069:         case 2:        // ROXL.B #qqq,Dy
                   4070:                CYCLE(12);
                   4071:                count = RegIRX;
                   4072:                count = (count == 0) ? 8 : count;
                   4073:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4074:                data = ACC.roxl_8(RegDY & 0xff, count);
1.1       root     4075:                RegDY = (RegDY & 0xffffff00) | data;
                   4076:                return;
                   4077:         case 3:        // ROL.B #qqq,Dy
                   4078:                CYCLE(6);
                   4079:                count = RegIRX;
                   4080:                count = (count == 0) ? 8 : count;
                   4081:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4082:                data = ACC.rol_8(RegDY & 0xff, count);
1.1       root     4083:                RegDY = (RegDY & 0xffffff00) | data;
                   4084:                return;
                   4085:         case 4:        // ASL.B Dx,Dy
                   4086:                CYCLE(8);
                   4087:                count = RegDX & 63;
                   4088:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4089:                data = ACC.asl_8(RegDY & 0xff, count);
1.1       root     4090:                RegDY = (RegDY & 0xffffff00) | data;
                   4091:                return;
                   4092:         case 5:        // LSL.B Dx,Dy
                   4093:                count = RegDX & 63;
                   4094:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   4095:                CYCLE(count <= 8 ? 6 : 8);
                   4096:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4097:                data = ACC.lsl_8(RegDY & 0xff, count);
1.1       root     4098:                RegDY = (RegDY & 0xffffff00) | data;
                   4099:                return;
                   4100:         case 6:        // ROXL.B Dx,Dy
                   4101:                CYCLE(12);
                   4102:                count = RegDX & 63;
                   4103:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4104:                data = ACC.roxl_8(RegDY & 0xff, count);
1.1       root     4105:                RegDY = (RegDY & 0xffffff00) | data;
                   4106:                return;
                   4107:         case 7:        // ROL.B Dx,Dy
                   4108:                CYCLE(8);
                   4109:                count = RegDX & 63;
                   4110:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4111:                data = ACC.rol_8(RegDY & 0xff, count);
1.1       root     4112:                RegDY = (RegDY & 0xffffff00) | data;
                   4113:                return;
                   4114:        }
                   4115: }
                   4116: 
                   4117: // %1110_qqq101_000yyy ASL.W #qqq,Dy
                   4118: // %1110_qqq101_001yyy LSL.W #qqq,Dy
                   4119: // %1110_qqq101_010yyy ROXL.W #qqq,Dy
                   4120: // %1110_qqq101_011yyy ROL.W #qqq,Dy
                   4121: // %1110_xxx101_100yyy ASL.W Dx,Dy
                   4122: // %1110_xxx101_101yyy LSL.W Dx,Dy
                   4123: // %1110_xxx101_110yyy ROXL.W Dx,Dy
                   4124: // %1110_xxx101_111yyy ROL.W Dx,Dy
                   4125: OP_DEF(asl_w_imm)
                   4126: {
                   4127:        int count;
                   4128:        uint32 data;
1.1.1.5 ! root     4129:        switch (eamode(ir)) {
1.1       root     4130:         case 0:        // ASL.W #qqq,Dy
                   4131:                CYCLE(6);
                   4132:                count = RegIRX;
                   4133:                count = (count == 0) ? 8 : count;
                   4134:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4135:                data = ACC.asl_16(RegDY & 0xffff, count);
1.1       root     4136:                RegDY = (RegDY & 0xffff0000) | data;
                   4137:                return;
                   4138:         case 1:        // LSL.W #qqq,Dy
                   4139:                CYCLE(4);
                   4140:                count = RegIRX;
                   4141:                count = (count == 0) ? 8 : count;
                   4142:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4143:                data = ACC.lsl_16(RegDY & 0xffff, count);
1.1       root     4144:                RegDY = (RegDY & 0xffff0000) | data;
                   4145:                return;
                   4146:         case 2:        // ROXL.W #qqq,Dy
                   4147:                CYCLE(12);
                   4148:                count = RegIRX;
                   4149:                count = (count == 0) ? 8 : count;
                   4150:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4151:                data = ACC.roxl_16(RegDY & 0xffff, count);
1.1       root     4152:                RegDY = (RegDY & 0xffff0000) | data;
                   4153:                return;
                   4154:         case 3:        // ROL.W #qqq,Dy
                   4155:                CYCLE(6);
                   4156:                count = RegIRX;
                   4157:                count = (count == 0) ? 8 : count;
                   4158:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4159:                data = ACC.rol_16(RegDY & 0xffff, count);
1.1       root     4160:                RegDY = (RegDY & 0xffff0000) | data;
                   4161:                return;
                   4162:         case 4:        // ASL.W Dx,Dy
                   4163:                CYCLE(8);
                   4164:                count = RegDX & 63;
                   4165:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4166:                data = ACC.asl_16(RegDY & 0xffff, count);
1.1       root     4167:                RegDY = (RegDY & 0xffff0000) | data;
                   4168:                return;
                   4169:         case 5:        // LSL.W Dx,Dy
                   4170:                count = RegDX & 63;
                   4171:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   4172:                CYCLE(count <= 16 ? 6 : 8);
                   4173:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4174:                data = ACC.lsl_16(RegDY & 0xffff, count);
1.1       root     4175:                RegDY = (RegDY & 0xffff0000) | data;
                   4176:                return;
                   4177:         case 6:        // ROXL.W Dx,Dy
                   4178:                CYCLE(12);
                   4179:                count = RegDX & 63;
                   4180:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4181:                data = ACC.roxl_16(RegDY & 0xffff, count);
1.1       root     4182:                RegDY = (RegDY & 0xffff0000) | data;
                   4183:                return;
                   4184:         case 7:        // ROL.W Dx,Dy
                   4185:                CYCLE(8);
                   4186:                count = RegDX & 63;
                   4187:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4188:                data = ACC.rol_16(RegDY & 0xffff, count);
1.1       root     4189:                RegDY = (RegDY & 0xffff0000) | data;
                   4190:                return;
                   4191:        }
                   4192: }
                   4193: 
                   4194: // %1110_qqq110_000yyy ASL.L #qqq,Dy
                   4195: // %1110_qqq110_001yyy LSL.L #qqq,Dy
                   4196: // %1110_qqq110_010yyy ROXL.L #qqq,Dy
                   4197: // %1110_qqq110_011yyy ROL.L #qqq,Dy
                   4198: // %1110_xxx110_100yyy ASL.L Dx,Dy
                   4199: // %1110_xxx110_101yyy LSL.L Dx,Dy
                   4200: // %1110_xxx110_110yyy ROXL.L Dx,Dy
                   4201: // %1110_xxx110_111yyy ROL.L Dx,Dy
                   4202: OP_DEF(asl_l_imm)
                   4203: {
                   4204:        int count;
1.1.1.5 ! root     4205:        switch (eamode(ir)) {
1.1       root     4206:         case 0:        // ASL.L #qqq,Dy
                   4207:                CYCLE(6);
                   4208:                count = RegIRX;
                   4209:                count = (count == 0) ? 8 : count;
                   4210:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4211:                RegDY = ACC.asl_32(RegDY, count);
1.1       root     4212:                return;
                   4213:         case 1:        // LSL.L #qqq,Dy
                   4214:                CYCLE(4);
                   4215:                count = RegIRX;
                   4216:                count = (count == 0) ? 8 : count;
                   4217:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4218:                RegDY = ACC.lsl_32(RegDY, count);
1.1       root     4219:                return;
                   4220:         case 2:        // ROXL.L #qqq,Dy
                   4221:                CYCLE(12);
                   4222:                count = RegIRX;
                   4223:                count = (count == 0) ? 8 : count;
                   4224:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4225:                RegDY = ACC.roxl_32(RegDY, count);
1.1       root     4226:                return;
                   4227:         case 3:        // ROL.L #qqq,Dy
                   4228:                CYCLE(6);
                   4229:                count = RegIRX;
                   4230:                count = (count == 0) ? 8 : count;
                   4231:                __assume(1 <= count && count <= 8);
1.1.1.5 ! root     4232:                RegDY = ACC.rol_32(RegDY, count);
1.1       root     4233:                return;
                   4234:         case 4:        // ASL.L Dx,Dy
                   4235:                CYCLE(8);
                   4236:                count = RegDX & 63;
                   4237:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4238:                RegDY = ACC.asl_32(RegDY, count);
1.1       root     4239:                return;
                   4240:         case 5:        // LSL.L Dx,Dy
                   4241:                count = RegDX & 63;
                   4242:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
                   4243:                CYCLE(count <= 32 ? 6 : 8);
                   4244:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4245:                RegDY = ACC.lsl_32(RegDY, count);
1.1       root     4246:                return;
                   4247:         case 6:        // ROXL.L Dx,Dy
                   4248:                CYCLE(12);
                   4249:                count = RegDX & 63;
                   4250:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4251:                RegDY = ACC.roxl_32(RegDY, count);
1.1       root     4252:                return;
                   4253:         case 7:        // ROL.L Dx,Dy
                   4254:                CYCLE(8);
                   4255:                count = RegDX & 63;
                   4256:                __assume(0 <= count && count < 64);
1.1.1.5 ! root     4257:                RegDY = ACC.rol_32(RegDY, count);
1.1       root     4258:                return;
                   4259:        }
                   4260: }
                   4261: 
                   4262: // %1110_000111_mmmrrr ASL.W <ea>
                   4263: OP_DEF(asl_w)
                   4264: {
                   4265:        CYCLE(6);
1.1.1.5 ! root     4266:        uint32 ea = cea_data_16();
        !          4267:        uint32 data = read_16(ea);
        !          4268:        data = ACC.asl_16(data, 1);
        !          4269:        write_16(ea, data);
1.1       root     4270: }
                   4271: 
                   4272: // %1110_001011_mmmrrr LSR.W <ea>
                   4273: OP_DEF(lsr_w)
                   4274: {
                   4275:        CYCLE(4);
1.1.1.5 ! root     4276:        uint32 ea = cea_data_16();
        !          4277:        uint32 data = read_16(ea);
        !          4278:        data = ACC.lsr_16(data, 1);
        !          4279:        write_16(ea, data);
1.1       root     4280: }
                   4281: 
                   4282: // %1110_001111_mmmrrr LSL.W <ea>
                   4283: OP_DEF(lsl_w)
                   4284: {
                   4285:        CYCLE(4);
1.1.1.5 ! root     4286:        uint32 ea = cea_data_16();
        !          4287:        uint32 data = read_16(ea);
        !          4288:        data = ACC.lsl_16(data, 1);
        !          4289:        write_16(ea, data);
1.1       root     4290: }
                   4291: 
                   4292: // %1110_010011_mmmrrr ROXR.W <ea>
                   4293: OP_DEF(roxr_w)
                   4294: {
                   4295:        CYCLE(4);
1.1.1.5 ! root     4296:        uint32 ea = cea_data_16();
        !          4297:        uint32 data = read_16(ea);
        !          4298:        data = ACC.roxr_16(data, 1);
        !          4299:        write_16(ea, data);
1.1       root     4300: }
                   4301: 
                   4302: // %1110_010111_mmmrrr ROXL.W <ea>
                   4303: OP_DEF(roxl_w)
                   4304: {
                   4305:        CYCLE(4);
1.1.1.5 ! root     4306:        uint32 ea = cea_data_16();
        !          4307:        uint32 data = read_16(ea);
        !          4308:        data = ACC.roxl_16(data, 1);
        !          4309:        write_16(ea, data);
1.1       root     4310: }
                   4311: 
                   4312: // %1110_011011_mmmrrr ROR.W <ea>
                   4313: OP_DEF(ror_w)
                   4314: {
                   4315:        CYCLE(6);
1.1.1.5 ! root     4316:        uint32 ea = cea_data_16();
        !          4317:        uint32 data = read_16(ea);
        !          4318:        data = ACC.ror_16(data, 1);
        !          4319:        write_16(ea, data);
1.1       root     4320: }
                   4321: 
                   4322: // %1110_011111_mmmrrr ROL.W <ea>
                   4323: OP_DEF(rol_w)
                   4324: {
                   4325:        CYCLE(6);
1.1.1.5 ! root     4326:        uint32 ea = cea_data_16();
        !          4327:        uint32 data = read_16(ea);
        !          4328:        data = ACC.rol_16(data, 1);
        !          4329:        write_16(ea, data);
1.1       root     4330: }
                   4331: 
                   4332: // %1110_100011_mmmrrr BFTST <ea>{#o:#w}
                   4333: OP_DEF(bftst)
                   4334: {
1.1.1.5 ! root     4335:        uint n = ir & 0x3f;
        !          4336:        ir2 = fetch_16();
1.1       root     4337: 
1.1.1.5 ! root     4338:        acc_bf bf(this);
1.1       root     4339:        if (n < 8) {
                   4340:                // BFTST Dn{#o:#w}
                   4341:                bf.LoadReg(n);
                   4342:        } else {
                   4343:                // BFTST <ea>{#o:#w}
1.1.1.5 ! root     4344:                uint32 ea = cea_ctrl();
1.1       root     4345:                bf.LoadMem(ea);
                   4346:        }
1.1.1.5 ! root     4347:        ACC.move_32(bf.data);
1.1       root     4348: }
                   4349: 
                   4350: // %1110_100111_mmmrrr BFEXTU <ea>{#o:#w},Dn
                   4351: OP_DEF(bfextu)
                   4352: {
1.1.1.5 ! root     4353:        uint n = ir & 0x3f;
        !          4354:        ir2 = fetch_16();
        !          4355:        uint dn = ir2 >> 12;
1.1       root     4356: 
1.1.1.5 ! root     4357:        acc_bf bf(this);
1.1       root     4358:        if (n < 8) {
                   4359:                // BFEXTU Dn{#o:#w},Dn
                   4360:                bf.LoadReg(n);
                   4361:        } else {
                   4362:                // BFEXTU <ea>{#o:#w},Dn
1.1.1.5 ! root     4363:                uint32 ea = cea_ctrl();
1.1       root     4364:                bf.LoadMem(ea);
                   4365:        }
                   4366:        // CCR は操作前のビットフィールドに対して
1.1.1.5 ! root     4367:        ACC.move_32(bf.data);
1.1       root     4368:        // 符号なしシフト
1.1.1.5 ! root     4369:        reg.D[dn] = bf.data >> (32 - bf.width);
1.1       root     4370: }
                   4371: 
                   4372: // %1110_101011_mmmrrr BFCHG <ea>{#o:#w}
                   4373: OP_DEF(bfchg)
                   4374: {
1.1.1.5 ! root     4375:        uint n = ir & 0x3f;
        !          4376:        ir2 = fetch_16();
1.1       root     4377: 
1.1.1.5 ! root     4378:        acc_bf bf(this);
1.1       root     4379:        if (n < 8) {
                   4380:                // BFCHG Dn{#o:#w}
                   4381:                bf.LoadReg(n);
                   4382:        } else if (n >= 0x3a) {
                   4383:                // BFCHG <ea> に PC 相対(と #imm) はない
1.1.1.5 ! root     4384:                op_illegal();
1.1       root     4385:        } else {
                   4386:                // BFCHG <ea>{#o:#w}
1.1.1.5 ! root     4387:                uint32 ea = cea_ctrl();
1.1       root     4388:                bf.LoadMem(ea);
                   4389:        }
                   4390:        // CCR は操作前のビットフィールドに対して
1.1.1.5 ! root     4391:        ACC.move_32(bf.data);
1.1       root     4392:        bf.data = ~bf.data;
                   4393:        bf.Store(n);
                   4394: }
                   4395: 
                   4396: // %1110_101111_mmmrrr BFEXTS <ea>{#o:#w},Dn
                   4397: OP_DEF(bfexts)
                   4398: {
1.1.1.5 ! root     4399:        uint n = ir & 0x3f;
        !          4400:        ir2 = fetch_16();
        !          4401:        uint dn = ir2 >> 12;
1.1       root     4402: 
1.1.1.5 ! root     4403:        acc_bf bf(this);
1.1       root     4404:        if (n < 8) {
                   4405:                // BFEXTS Dn{#o:#w},Dn
                   4406:                bf.LoadReg(n);
                   4407:        } else {
                   4408:                // BFEXTS <ea>{#o:#w},Dn
1.1.1.5 ! root     4409:                uint32 ea = cea_ctrl();
1.1       root     4410:                bf.LoadMem(ea);
                   4411:        }
                   4412:        // CCR は操作前のビットフィールドに対して
1.1.1.5 ! root     4413:        ACC.move_32(bf.data);
1.1       root     4414:        // 符号付きシフト
                   4415:        // XXX 負数の右シフト
1.1.1.5 ! root     4416:        reg.D[dn] = ((int32)bf.data) >> (32 - bf.width);
1.1       root     4417: }
                   4418: 
                   4419: // %1110_110011_mmmrrr BFCLR <ea>{#o:#w}
                   4420: OP_DEF(bfclr)
                   4421: {
1.1.1.5 ! root     4422:        uint n = ir & 0x3f;
        !          4423:        ir2 = fetch_16();
1.1       root     4424: 
1.1.1.5 ! root     4425:        acc_bf bf(this);
1.1       root     4426:        if (n < 8) {
                   4427:                // BFCLR Dn{#o:#w}
                   4428:                bf.LoadReg(n);
                   4429:        } else if (n >= 0x3a) {
                   4430:                // BFCLR <ea> に PC 相対(と #imm) はない
1.1.1.5 ! root     4431:                op_illegal();
1.1       root     4432:        } else {
                   4433:                // BFCLR <ea>{#o:#w}
1.1.1.5 ! root     4434:                uint32 ea = cea_ctrl();
1.1       root     4435:                bf.LoadMem(ea);
                   4436:        }
                   4437:        // CCR は操作前のビットフィールドに対して
1.1.1.5 ! root     4438:        ACC.move_32(bf.data);
1.1       root     4439:        bf.data = 0;
                   4440:        bf.Store(n);
                   4441: }
                   4442: 
                   4443: // %1110_110111_mmmrrr BFFFO <ea>{#o:#w},Dn
                   4444: OP_DEF(bfffo)
                   4445: {
1.1.1.5 ! root     4446:        uint n = ir & 0x3f;
        !          4447:        ir2 = fetch_16();
        !          4448:        uint dn = ir2 >> 12;
1.1       root     4449: 
1.1.1.5 ! root     4450:        acc_bf bf(this);
1.1       root     4451:        if (n < 8) {
                   4452:                // BFFFO Dn{#o:#w},Dn
                   4453:                bf.LoadReg(n);
                   4454:        } else {
                   4455:                // BFFFO <ea>{#o:#w},Dn
1.1.1.5 ! root     4456:                uint32 ea = cea_ctrl();
1.1       root     4457:                bf.LoadMem(ea);
                   4458:        }
                   4459:        // CCR は操作前のビットフィールドに対して
1.1.1.5 ! root     4460:        ACC.move_32(bf.data);
1.1       root     4461:        // 1 になっているビットを探す
                   4462:        for (; (int)bf.width-- > 0 && (int32)bf.data >= 0; bf.data <<= 1) {
                   4463:                bf.offset++;
                   4464:        }
1.1.1.5 ! root     4465:        reg.D[dn] = bf.offset;
1.1       root     4466: }
                   4467: 
                   4468: // %1110_111011_mmmrrr BFSET <ea>{#o:#w}
                   4469: OP_DEF(bfset)
                   4470: {
1.1.1.5 ! root     4471:        uint n = ir & 0x3f;
        !          4472:        ir2 = fetch_16();
1.1       root     4473: 
1.1.1.5 ! root     4474:        acc_bf bf(this);
1.1       root     4475:        if (n < 8) {
                   4476:                // BFSET Dn{#o:#w}
                   4477:                bf.LoadReg(n);
                   4478:        } else if (n >= 0x3a) {
                   4479:                // BFSET <ea> に PC 相対(と #imm) はない
1.1.1.5 ! root     4480:                op_illegal();
1.1       root     4481:        } else {
                   4482:                // BFSET <ea>{#o:#w}
1.1.1.5 ! root     4483:                uint32 ea = cea_ctrl();
1.1       root     4484:                bf.LoadMem(ea);
                   4485:        }
                   4486:        // CCR は操作前のビットフィールドに対して
1.1.1.5 ! root     4487:        ACC.move_32(bf.data);
1.1       root     4488:        bf.data = 0xffffffff;
                   4489:        bf.Store(n);
                   4490: }
                   4491: 
                   4492: // %1110_111111_mmmrrr BFINS Dn,<ea>{#o:#w}
                   4493: OP_DEF(bfins)
                   4494: {
1.1.1.5 ! root     4495:        uint n = ir & 0x3f;
        !          4496:        ir2 = fetch_16();
        !          4497:        uint dn = ir2 >> 12;
1.1       root     4498: 
1.1.1.5 ! root     4499:        acc_bf bf(this);
1.1       root     4500:        if (n < 8) {
                   4501:                // BFINS Dm,Dn{#o:#w}
                   4502:                bf.LoadReg(n);
                   4503:        } else if (n >= 0x3a) {
                   4504:                // BFINS Dn,<ea> に PC 相対(と #imm) はない
1.1.1.5 ! root     4505:                op_illegal();
1.1       root     4506:        } else {
                   4507:                // BFINS Dn,<ea>{#o:#w}
1.1.1.5 ! root     4508:                uint32 ea = cea_ctrl();
1.1       root     4509:                bf.LoadMem(ea);
                   4510:        }
1.1.1.5 ! root     4511:        bf.data = reg.D[dn] << (32 - bf.width);
1.1       root     4512:        // BFINS のみ CCR は操作後のビットフィールドに対して
1.1.1.5 ! root     4513:        ACC.move_32(bf.data);
1.1       root     4514:        bf.Store(n);
                   4515: }
                   4516: 
                   4517: // %1111_000nnn_nnnnnn MMU_OP
                   4518: OP_DEF(mmuop)
                   4519: {
1.1.1.5 ! root     4520:        ir2 = fetch_16();
        !          4521:        switch ((ir2 >> 8) & 0xff) {
1.1       root     4522:         case (0x0800 >> 8):
                   4523:         case (0x0900 >> 8):
                   4524:         case (0x0c00 >> 8):
                   4525:         case (0x0d00 >> 8):
                   4526:         // %000_01n00_000_00000        PMOVE.L <ea>,TTn
                   4527:         // %000_01n01_000_00000        PMOVEFD.L <ea>,TTn
                   4528:         {
                   4529:                CYCLE2(12, 14);
1.1.1.5 ! root     4530:                uint32 ea = cea_copro();
        !          4531:                uint32 data = read_32(ea);
        !          4532:                int n = (ir2 >> 10) & 1;
        !          4533:                SetTT(n, data);
        !          4534:                if ((ir2 & 0x0100) == 0)
        !          4535:                        atc.flush();
1.1       root     4536:                break;
                   4537:         }
                   4538:         case (0x0a00 >> 8):
                   4539:         case (0x0e00 >> 8):
                   4540:         // %000_01n10_000_00000        PMOVE.L TTn,<ea>
                   4541:         {
                   4542:                CYCLE(8);
1.1.1.5 ! root     4543:                uint32 ea = cea_copro();
        !          4544:                int n = (ir2 >> 10) & 1;
        !          4545:                write_32(ea, GetTT(n));
1.1       root     4546:                break;
                   4547:         }
                   4548:         case (0x2000 >> 8):
                   4549:         // %001_00000_000_00000        PLOADW SFC,<ea>
                   4550:         // %001_00000_000_00001        PLOADW DFC,<ea>
                   4551:         // %001_00000_000_01yyy        PLOADW Dy,<ea>
                   4552:         // %001_00000_000_10nnn        PLOADW #<imm>,<ea>
                   4553:         {
1.1.1.5 ! root     4554: putlog(0, "ploadw");
        !          4555:                mmu_op_pload();
1.1       root     4556:                break;
                   4557:         }
                   4558:         case (0x2200 >> 8):
                   4559:         // %001_00010_000_00000        PLOADR SFC,<ea>
                   4560:         // %001_00010_000_00001        PLOADR DFC,<ea>
                   4561:         // %001_00010_000_01yyy        PLOADR Dy,<ea>
                   4562:         // %001_00010_000_10nnn        PLOADR #<imm>,<ea>
                   4563:         {
1.1.1.5 ! root     4564: putlog(0, "ploadr");
        !          4565:                mmu_op_pload();
1.1       root     4566:                break;
                   4567:         }
                   4568:         case (0x2400 >> 8):
                   4569:         // %001_00100_000_00000        PFLUSHA
                   4570:         {
                   4571:                CYCLE2(12, 14);
1.1.1.5 ! root     4572:                atc.flush();
1.1       root     4573:                break;
                   4574:         }
                   4575:         case (0x3000 >> 8):
                   4576:         // %001_10000_nnn_00000        PFLUSH SFC,#<mask>
                   4577:         // %001_10000_nnn_00001        PFLUSH DFC,#<mask>
                   4578:         // %001_10000_nnn_01yyy        PFLUSH Dy,#<mask>
                   4579:         // %001_10000_nnn_10nnn        PFLUSH #<imm>,#<mask>
                   4580:         {
1.1.1.5 ! root     4581:                mmu_op_pflush();
1.1       root     4582:                break;
                   4583:         }
                   4584:         case (0x3800 >> 8):
                   4585:         // %001_11000_nnn_00000        PFLUSH SFC,#<mask>,<ea>
                   4586:         // %001_11000_nnn_00001        PFLUSH DFC,#<mask>,<ea>
                   4587:         // %001_11000_nnn_01yyy        PFLUSH Dy,#<mask>,<ea>
                   4588:         // %001_11000_nnn_10nnn        PFLUSH #<imm>,#<mask>,<ea>
                   4589:         {
1.1.1.5 ! root     4590:                mmu_op_pflush_ea();
1.1       root     4591:                break;
                   4592:         }
                   4593:         case (0x4000 >> 8):
                   4594:         case (0x4100 >> 8):
                   4595:         // %010_00000_000_00000        PMOVE.L <ea>,TC
                   4596:         // %010_00001_000_00000        PMOVEFD.L <ea>,TC
                   4597:         {
                   4598:                // たぶん
                   4599:                // 無効→有効が (38, 40)
                   4600:                // 有効→無効が (56, 58)
                   4601:                // 無効→無効が (14, 16) ってことだと思うんだけど。
                   4602:                CYCLE2(14, 16);
1.1.1.5 ! root     4603:                uint32 ea = cea_copro();
        !          4604:                uint32 data = read_32(ea);
        !          4605:                if (SetTC(data) == false) {
        !          4606:                        Exception(M68K::EXCEP_MMU_CONFIG);
1.1       root     4607:                        break;
                   4608:                }
1.1.1.5 ! root     4609:                if ((ir2 & 0x0100) == 0)
        !          4610:                        atc.flush();
1.1       root     4611:                break;
                   4612:         }
                   4613:         case (0x4200 >> 8):
                   4614:         // %010_00010_000_00000        PMOVE.L TC,<ea>
                   4615:         {
                   4616:                CYCLE2(4, 5);
1.1.1.5 ! root     4617:                uint32 ea = cea_copro();
        !          4618:                write_32(ea, GetTC());
1.1       root     4619:                break;
                   4620:         }
                   4621:         case (0x4800 >> 8):
                   4622:         case (0x4900 >> 8):
                   4623:         // %010_01000_000_00000        PMOVE.Q <ea>,SRP
                   4624:         // %010_01001_000_00000        PMOVEFD.Q <ea>,SRP
                   4625:         {
                   4626:                // たぶん有効になる時が (12, 14)
                   4627:                // それ以外が (28, 30) ってことかな。
                   4628:                CYCLE2(28, 30);
1.1.1.5 ! root     4629:                uint32 ea = cea_copro();
        !          4630:                uint32 h = read_32(ea);
        !          4631:                uint32 l = read_32(ea + 4);
        !          4632:                if (SetSRP(h, l) == false) {
        !          4633:                        Exception(M68K::EXCEP_MMU_CONFIG);
        !          4634:                        break;
        !          4635:                }
        !          4636:                if ((ir2 & 0x0100) == 0)
        !          4637:                        atc.flush();
1.1       root     4638:                break;
                   4639:         }
                   4640:         case (0x4a00 >> 8):
                   4641:         // %010_01010_000_00000        PMOVE.Q SRP,<ea>
                   4642:         {
                   4643:                CYCLE2(4, 5);
1.1.1.5 ! root     4644:                uint32 ea = cea_copro();
        !          4645:                write_32(ea,     GetSRPh());
        !          4646:                write_32(ea + 4, GetSRPl());
1.1       root     4647:                break;
                   4648:         }
                   4649:         case (0x4c00 >> 8):
                   4650:         case (0x4d00 >> 8):
                   4651:         // %010_01100_000_00000        PMOVE.Q <ea>,CRP
                   4652:         // %010_01101_000_00000        PMOVEFD.Q <ea>,CRP
                   4653:         {
                   4654:                // たぶん有効になる時が (12, 14)
                   4655:                // それ以外が (28, 30) ってことかな。
                   4656:                CYCLE2(28, 30);
1.1.1.5 ! root     4657:                uint32 ea = cea_copro();
        !          4658:                uint32 h = read_32(ea);
        !          4659:                uint32 l = read_32(ea + 4);
        !          4660:                if (SetCRP(h, l) == false) {
        !          4661:                        Exception(M68K::EXCEP_MMU_CONFIG);
        !          4662:                        break;
        !          4663:                }
        !          4664:                if ((ir2 & 0x0100) == 0)
        !          4665:                        atc.flush();
1.1       root     4666:                break;
                   4667:         }
                   4668:         case (0x4e00 >> 8):
                   4669:         // %010_01110_000_00000        PMOVE.Q CRP,<ea>
                   4670:         {
                   4671:                CYCLE2(4, 5);
1.1.1.5 ! root     4672:                uint32 ea = cea_copro();
        !          4673:                write_32(ea,     GetCRPh());
        !          4674:                write_32(ea + 4, GetCRPl());
1.1       root     4675:                break;
                   4676:         }
                   4677:         case (0x6000 >> 8):
                   4678:         // %011_00000_000_00000        PMOVE.W <ea>,MMUSR
                   4679:         {
                   4680:                CYCLE(6);
1.1.1.5 ! root     4681:                uint32 ea = cea_copro();
        !          4682:                uint16 data = read_16(ea);
        !          4683:                SetMMUSR(data);
1.1       root     4684:                break;
                   4685:         }
                   4686:         case (0x6200 >> 8):
                   4687:         // %011_00010_000_00000        PMOVE.W MMUSR,<ea>
                   4688:         {
                   4689:                CYCLE2(4, 5);
1.1.1.5 ! root     4690:                uint32 ea = cea_copro();
        !          4691:                write_16(ea, GetMMUSR());
1.1       root     4692:                break;
                   4693:         }
                   4694:         case (0x8000 >> 8):
                   4695:         case (0x8400 >> 8):
                   4696:         case (0x8800 >> 8):
                   4697:         case (0x8c00 >> 8):
                   4698:         case (0x9000 >> 8):
                   4699:         case (0x9400 >> 8):
                   4700:         case (0x9800 >> 8):
                   4701:         case (0x9c00 >> 8):
                   4702:         // %100_nnn00_000_00000        PTESTW SFC,<ea>,#<level>
                   4703:         // %100_nnn00_000_00001        PTESTW DFC,<ea>,#<level>
                   4704:         // %100_nnn00_000_01yyy        PTESTW Dy,<ea>,#<level>
                   4705:         // %100_nnn00_000_10nnn        PTESTW #<imm>,<ea>,#<level>
                   4706:         {
1.1.1.5 ! root     4707:                mmu_op_ptest();
1.1       root     4708:                break;
                   4709:         }
                   4710:         case (0x8100 >> 8):
                   4711:         case (0x8500 >> 8):
                   4712:         case (0x8900 >> 8):
                   4713:         case (0x8d00 >> 8):
                   4714:         case (0x9100 >> 8):
                   4715:         case (0x9500 >> 8):
                   4716:         case (0x9900 >> 8):
                   4717:         case (0x9d00 >> 8):
                   4718:         // %100_nnn01_nnn_00000        PTESTW SFC,<ea>,#<level>,An
                   4719:         // %100_nnn01_nnn_00001        PTESTW DFC,<ea>,#<level>,An
                   4720:         // %100_nnn01_nnn_01yyy        PTESTW Dy,<ea>,#<level>,An
                   4721:         // %100_nnn01_nnn_10nnn        PTESTW #<imm>,<ea>,#<level>,An
                   4722:         {
1.1.1.5 ! root     4723:                mmu_op_ptest();
1.1       root     4724:                break;
                   4725:         }
                   4726:         case (0x8200 >> 8):
                   4727:         case (0x8600 >> 8):
                   4728:         case (0x8a00 >> 8):
                   4729:         case (0x8e00 >> 8):
                   4730:         case (0x9200 >> 8):
                   4731:         case (0x9600 >> 8):
                   4732:         case (0x9a00 >> 8):
                   4733:         case (0x9e00 >> 8):
                   4734:         // %100_nnn10_000_00000        PTESTR SFC,<ea>,#<level>
                   4735:         // %100_nnn10_000_00001        PTESTR DFC,<ea>,#<level>
                   4736:         // %100_nnn10_000_01yyy        PTESTR Dy,<ea>,#<level>
                   4737:         // %100_nnn10_000_10nnn        PTESTR #<imm>,<ea>,#<level>
                   4738:         {
1.1.1.5 ! root     4739:                mmu_op_ptest();
1.1       root     4740:                break;
                   4741:         }
                   4742:         case (0x8300 >> 8):
                   4743:         case (0x8700 >> 8):
                   4744:         case (0x8b00 >> 8):
                   4745:         case (0x8f00 >> 8):
                   4746:         case (0x9300 >> 8):
                   4747:         case (0x9700 >> 8):
                   4748:         case (0x9b00 >> 8):
                   4749:         case (0x9f00 >> 8):
                   4750:         // %100_nnn11_nnn_00000        PTESTR SFC,<ea>,#<level>,An
                   4751:         // %100_nnn11_nnn_00001        PTESTR DFC,<ea>,#<level>,An
                   4752:         // %100_nnn11_nnn_01yyy        PTESTR Dy,<ea>,#<level>,An
                   4753:         // %100_nnn11_nnn_10nnn        PTESTR #<imm>,<ea>,#<level>,An
                   4754:         {
1.1.1.5 ! root     4755:                mmu_op_ptest();
1.1       root     4756:                break;
                   4757:         }
                   4758:         default:
                   4759:                OP_FUNC(illegal);
                   4760:                break;
                   4761:        }
                   4762: }
                   4763: 
                   4764: // %1111_001000_nnnnnn FPGEN
                   4765: OP_DEF(fpgen)
                   4766: {
1.1.1.5 ! root     4767:        if (has_fpu == 0) {
        !          4768:                op_fline();
1.1       root     4769:                return;
                   4770:        }
                   4771: 
1.1.1.5 ! root     4772:        fpu_op_start();
1.1       root     4773: 
1.1.1.5 ! root     4774:        ir2 = fetch_16();
        !          4775:        switch (ir2 >> 13) {
1.1       root     4776:         case 0:
1.1.1.5 ! root     4777:                fpu_op_fgen_reg();
1.1       root     4778:                break;
                   4779:         case 1:
1.1.1.5 ! root     4780:                fpu_op_illg();
1.1       root     4781:                break;
                   4782:         case 2:
1.1.1.5 ! root     4783:                fpu_op_fgen_mem();
1.1       root     4784:                break;
                   4785:         case 3:
                   4786:         {
                   4787:                // FMOVE reg,<ea> はサイズごとに分岐
1.1.1.5 ! root     4788:                int size = (ir2 >> 10) & 7;
1.1       root     4789:                switch (size) {
                   4790:                 case SIZE_B:
1.1.1.5 ! root     4791:                        fpu_op_fmove_b_mem();
1.1       root     4792:                        break;
                   4793:                 case SIZE_W:
1.1.1.5 ! root     4794:                        fpu_op_fmove_w_mem();
1.1       root     4795:                        break;
                   4796:                 case SIZE_L:
1.1.1.5 ! root     4797:                        fpu_op_fmove_l_mem();
1.1       root     4798:                        break;
                   4799:                 case SIZE_S:
1.1.1.5 ! root     4800:                        fpu_op_fmove_s_mem();
1.1       root     4801:                        break;
                   4802:                 case SIZE_D:
1.1.1.5 ! root     4803:                        fpu_op_fmove_d_mem();
1.1       root     4804:                        break;
                   4805:                 case SIZE_X:
1.1.1.5 ! root     4806:                        fpu_op_fmove_x_mem();
1.1       root     4807:                        break;
                   4808:                 case SIZE_P:
                   4809:                 case 7:
1.1.1.5 ! root     4810:                        fpu_op_fmove_p_mem();
1.1       root     4811:                        break;
                   4812:                }
                   4813:                break;
                   4814:         }
                   4815:         case 4:
1.1.1.5 ! root     4816:                fpu_op_fmovem_ea2ctl();
1.1       root     4817:                break;
                   4818:         case 5:
1.1.1.5 ! root     4819:                fpu_op_fmovem_ctl2ea();
1.1       root     4820:                break;
                   4821:         case 6:
1.1.1.5 ! root     4822:                fpu_op_fmovem_ea2reg();
1.1       root     4823:                break;
                   4824:         case 7:
1.1.1.5 ! root     4825:                fpu_op_fmovem_reg2ea();
1.1       root     4826:                break;
                   4827:        }
                   4828: }
                   4829: 
                   4830: // %1111_001001_nnnnnn FScc.B <ea>
                   4831: // %1111_001001_001yyy FDBcc Dy,<label>
                   4832: // %1111_001001_111010 FTRAPcc.W #<imm>
                   4833: // %1111_001001_111011 FTRAPcc.L #<imm>
                   4834: // %1111_001001_111100 FTRAPcc
                   4835: OP_DEF(fxcc)
                   4836: {
1.1.1.5 ! root     4837:        if (has_fpu == 0) {
        !          4838:                op_fline();
1.1       root     4839:                return;
                   4840:        }
                   4841: 
1.1.1.5 ! root     4842:        fpu_op_start();
1.1       root     4843: 
1.1.1.5 ! root     4844:        ir2 = fetch_16();
        !          4845:        switch (eamode(ir)) {
1.1       root     4846:         case 1:
1.1.1.5 ! root     4847:                fpu_op_fdbcc();
1.1       root     4848:                return;
                   4849:         case 7:
1.1.1.5 ! root     4850:                switch (ir & 7) {
1.1       root     4851:                 case 0:
                   4852:                 case 1:
1.1.1.5 ! root     4853:                        fpu_op_fscc();
1.1       root     4854:                        return;
                   4855:                 case 2:
1.1.1.5 ! root     4856:                        fpu_op_ftrapcc_w();
1.1       root     4857:                        return;
                   4858:                 case 3:
1.1.1.5 ! root     4859:                        fpu_op_ftrapcc_l();
1.1       root     4860:                        return;
                   4861:                 case 4:
1.1.1.5 ! root     4862:                        fpu_op_ftrapcc();
1.1       root     4863:                        return;
                   4864:                 default:
                   4865:                        break;
                   4866:                }
                   4867:                break;
                   4868:         default:
1.1.1.5 ! root     4869:                fpu_op_fscc();
1.1       root     4870:                return;
                   4871:        }
                   4872: }
                   4873: 
                   4874: // %1111_001010_nnnnnn FBcc.W <label>
                   4875: OP_DEF(fbcc_w)
                   4876: {
1.1.1.5 ! root     4877:        if (has_fpu == 0) {
        !          4878:                op_fline();
1.1       root     4879:                return;
                   4880:        }
                   4881: 
1.1.1.5 ! root     4882:        fpu_op_start();
1.1       root     4883: 
1.1.1.5 ! root     4884:        fpu_op_fbcc_w();
1.1       root     4885: }
                   4886: 
                   4887: // %1111_001011_nnnnnn FBcc.L <label>
                   4888: OP_DEF(fbcc_l)
                   4889: {
1.1.1.5 ! root     4890:        if (has_fpu == 0) {
        !          4891:                op_fline();
1.1       root     4892:                return;
                   4893:        }
                   4894: 
1.1.1.5 ! root     4895:        fpu_op_start();
1.1       root     4896: 
1.1.1.5 ! root     4897:        fpu_op_fbcc_l();
1.1       root     4898: }
                   4899: 
                   4900: // %1111_001100_nnnnnn FSAVE <ea>
                   4901: OP_DEF(fsave)
                   4902: {
1.1.1.5 ! root     4903:        if (has_fpu == 0) {
        !          4904:                op_fline();
1.1       root     4905:                return;
                   4906:        }
                   4907: 
                   4908:        SUPERVISOR_OP;
                   4909: 
1.1.1.5 ! root     4910:        fpu_op_fsave();
1.1       root     4911: }
                   4912: 
                   4913: // %1111_001101_nnnnnn FRESTORE <ea>
                   4914: OP_DEF(frestore)
                   4915: {
1.1.1.5 ! root     4916:        if (has_fpu == 0) {
        !          4917:                op_fline();
1.1       root     4918:                return;
                   4919:        }
                   4920: 
                   4921:        SUPERVISOR_OP;
                   4922: 
1.1.1.5 ! root     4923:        fpu_op_frestore();
1.1       root     4924: }
                   4925: 
                   4926: // %1111_nnnnnn_nnnnnn F-Line
                   4927: OP_DEF(fline)
                   4928: {
                   4929:        CYCLE2(18, 20);
                   4930: 
1.1.1.5 ! root     4931:        if (fline_callback) {
        !          4932:                if (fline_callback(this, fline_arg)) {
1.1       root     4933:                        return;
                   4934:                }
                   4935:        }
                   4936:        // F系列命令例外
1.1.1.5 ! root     4937:        Exception(M68K::EXCEP_FLINE);
1.1       root     4938: }
                   4939: 
                   4940: // illegal instructions
                   4941: OP_DEF(illegal)
                   4942: {
                   4943:        CYCLE2(18, 20);
                   4944:        // 不当命令例外
1.1.1.5 ! root     4945:        Exception(M68K::EXCEP_ILLEGAL);
1.1       root     4946: }

unix.superglobalmegacorp.com

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