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

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

unix.superglobalmegacorp.com

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