Annotation of nono/m680x0/m680x0ops.cpp, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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