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

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

unix.superglobalmegacorp.com

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