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

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) {
1.1.1.3 ! root     2630:         case 0x00:                     // TRAP #0
        !          2631:                CYCLE3(trap);
        !          2632:                // TRAP#0 例外 (NetBSD システムコール表示のため別処理)
        !          2633:                ExceptionTrap0();
        !          2634:                return;
        !          2635: 
        !          2636:         case 0x01 ... 0x0e:// TRAP #<vector>
1.1.1.2   root     2637:                CYCLE3(trap);
1.1       root     2638:                // TRAP#N 例外
                   2639:                Exception(M68K::EXCEP_TRAP0 + n);
                   2640:                return;
                   2641: 
                   2642:         case 0x0f:                     // TRAP #15
1.1.1.2   root     2643:                CYCLE3(trap);
1.1       root     2644:                // TRAP#15 例外 (IOCS コール表示のためこれだけ別処理)
                   2645:                ExceptionTrap15();
                   2646:                return;
                   2647: 
                   2648:         case 0x10:
                   2649:         case 0x11:
                   2650:         case 0x12:
                   2651:         case 0x13:
                   2652:         case 0x14:
                   2653:         case 0x15:
                   2654:         case 0x16:
                   2655:         case 0x17:                     // LINK.W Ay,#<imm>
                   2656:         {
1.1.1.2   root     2657:                CYCLE3(link_w);
1.1       root     2658:                // レジスタやスタックを変更する前にフェッチとセーブをしないと、
                   2659:                // ページフォルトで再実行できなくなる
                   2660:                int32 imm = (int32)(int16)fetch_2();
                   2661:                ops_link(imm);
                   2662:                return;
                   2663:         }
                   2664: 
                   2665:         case 0x18:
                   2666:         case 0x19:
                   2667:         case 0x1a:
                   2668:         case 0x1b:
                   2669:         case 0x1c:
                   2670:         case 0x1d:
                   2671:         case 0x1e:
                   2672:         case 0x1f:                     // UNLK Ay
1.1.1.2   root     2673:                CYCLE3(unlk);
1.1       root     2674:                // ページフォルトに備えて保存する
                   2675:                save_reg_pi(7);
                   2676:                reg.A[7] = RegAY;
                   2677:                RegAY = pop_4();
                   2678:                return;
                   2679: 
                   2680:         case 0x20:
                   2681:         case 0x21:
                   2682:         case 0x22:
                   2683:         case 0x23:
                   2684:         case 0x24:
                   2685:         case 0x25:
                   2686:         case 0x26:
                   2687:         case 0x27:                     // MOVE.L Ay,USP
                   2688:                SUPERVISOR_OP;
1.1.1.2   root     2689:                CYCLE3(move_an_usp);
1.1       root     2690:                reg.usp = RegAY;
                   2691:                return;
                   2692: 
                   2693:         case 0x28:
                   2694:         case 0x29:
                   2695:         case 0x2a:
                   2696:         case 0x2b:
                   2697:         case 0x2c:
                   2698:         case 0x2d:
                   2699:         case 0x2e:
                   2700:         case 0x2f:                     // MOVE.L USP,Ay
                   2701:                SUPERVISOR_OP;
1.1.1.2   root     2702:                CYCLE3(move_usp_an);
1.1       root     2703:                RegAY = reg.usp;
                   2704:                return;
                   2705: 
                   2706:         case 0x30:                     // RESET
1.1.1.2   root     2707:                // CYCLE3() は int8 なので。
1.1       root     2708:                CYCLE(518);
                   2709:                ops_reset();
                   2710:                return;
                   2711: 
                   2712:         case 0x31:                     // NOP
1.1.1.2   root     2713:                CYCLE3(nop);
1.1       root     2714:                // XXX ほんとは何かするらしいけど
                   2715:                return;
                   2716: 
                   2717:         case 0x32:                     // STOP #<imm>
                   2718:                SUPERVISOR_OP;
1.1.1.2   root     2719:                CYCLE3(stop);
1.1       root     2720:                ops_stop();
                   2721:                return;
                   2722: 
                   2723:         case 0x33:                     // RTE
                   2724:                SUPERVISOR_OP;
                   2725:                ops_rte();
                   2726:                return;
                   2727: 
                   2728:         case 0x34:                     // RTD #<imm>
                   2729:         {
1.1.1.2   root     2730:                CYCLE3(rtd);
1.1       root     2731:                // ページフォルトに備えて保存する
                   2732:                save_reg_pi(7);
                   2733:                uint32 disp = fetch_2();
                   2734:                Jump(pop_4());
                   2735:                reg.A[7] += (int32)(int16)disp;
                   2736:                return;
                   2737:         }
                   2738: 
                   2739:         case 0x35:                     // RTS
1.1.1.2   root     2740:                CYCLE3(rts);
1.1       root     2741:                // ページフォルトに備えて保存する
                   2742:                save_reg_pi(7);
                   2743:                Jump(pop_4());
                   2744:                return;
                   2745: 
                   2746:         case 0x36:                     // TRAPV
                   2747:                if (CCR.IsV()) {
1.1.1.2   root     2748:                        CYCLE3(trapv_excep);
1.1       root     2749:                        Exception(M68K::EXCEP_TRAPV);
                   2750:                } else {
1.1.1.2   root     2751:                        CYCLE3(trapv);
1.1       root     2752:                }
                   2753:                return;
                   2754: 
                   2755:         case 0x37:                     // RTR
1.1.1.2   root     2756:                CYCLE3(rtr);
1.1       root     2757:                // ページフォルトに備えて保存する
                   2758:                save_reg_pi(7);
                   2759:                CCR.Set(pop_2());
                   2760:                Jump(pop_4());
                   2761:                return;
                   2762: 
                   2763:         case 0x3a:                     // MOVEC.L Rc,Rn
                   2764:                ops_movec_rc_rn();
                   2765:                return;
                   2766: 
                   2767:         case 0x3b:                     // MOVEC.L Rn,Rc
                   2768:                ops_movec_rn_rc();
                   2769:                return;
                   2770: 
                   2771:         default:
                   2772:                op_illegal();
                   2773:                return;
                   2774:        }
                   2775: }
                   2776: 
                   2777: // %0100_111010_mmmrrr ..m..rxwp. 034  JSR <ea>
                   2778: OP_DEF(jsr)
                   2779: {
1.1.1.2   root     2780:        CYCLE3(jsr);
1.1       root     2781:        uint32 ea = cea_ctrl();
                   2782:        uint32 return_addr = reg.pc;
                   2783: 
                   2784:        // ページフォルトに備えて保存する。
                   2785:        save_reg_pd(7);
                   2786:        push_4(return_addr);
                   2787:        Jump(ea);
                   2788: }
                   2789: 
                   2790: // %0100_111011_mmmrrr ..m..rxwp. 034  JMP <ea>
                   2791: OP_DEF(jmp)
                   2792: {
1.1.1.2   root     2793:        CYCLE3(jmp);
1.1       root     2794:        // 実際には CEA ではなく JEA の実行時間を足すんだがまあいいか
                   2795:        uint32 ea = cea_ctrl();
                   2796:        Jump(ea);
                   2797: }
                   2798: 
                   2799: // %0101_qqq000_mmmrrr d.m+-rxw.. 034  ADDQ.B #qqq,<ea>
                   2800: OP_DEF(addq_b)
                   2801: {
                   2802:        uint n = ir & 0x3f;
                   2803: 
                   2804:        uint32 src = RegIRX;
                   2805:        src = (src == 0) ? 8 : src;
                   2806:        if (n < 8) {
                   2807:                // ADDQ.B #qqq,Dn
1.1.1.2   root     2808:                CYCLE3(addq_rn);
1.1       root     2809:                uint32 data = ACC.add_8(src, reg.D[n] & 0xff);
                   2810:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
                   2811:        } else {
                   2812:                // ADDQ.B #qqq,<ea>
1.1.1.2   root     2813:                CYCLE3(addq_ea);
1.1       root     2814:                uint32 ea = cea_data_1();
                   2815:                uint32 data = read_1(ea);
                   2816:                data = ACC.add_8(src, data);
                   2817:                write_1(ea, data);
                   2818:        }
                   2819: }
                   2820: 
                   2821: // %0101_qqq001_mmmrrr d.m+-rxw.. 034  ADDQ.W #qqq,<ea>
                   2822: // %0101_qqq001_001yyy .a........ 034  ADDQ.W #qqq,Ay (.Lと等価)
                   2823: OP_DEF(addq_w)
                   2824: {
                   2825:        uint n = ir & 0x3f;
                   2826: 
                   2827:        uint32 src = RegIRX;
                   2828:        src = (src == 0) ? 8 : src;
                   2829:        if (n < 8) {
                   2830:                // ADDQ.W #qqq,Dn
1.1.1.2   root     2831:                CYCLE3(addq_rn);
1.1       root     2832:                uint32 data = ACC.add_16(src, reg.D[n] & 0xffff);
                   2833:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
                   2834:        } else if (n < 16) {
                   2835:                // ADDQ.W #qqq,An は ADDQ.L と等価
                   2836:                // フラグは変化しない
1.1.1.2   root     2837:                CYCLE3(addq_rn);
1.1       root     2838:                reg.R[n] += src;
                   2839:        } else {
                   2840:                // ADDQ.W #qqq,<ea>
1.1.1.2   root     2841:                CYCLE3(addq_ea);
1.1       root     2842:                uint32 ea = cea_data_2();
                   2843:                uint32 data = read_2(ea);
                   2844:                data = ACC.add_16(src, data);
                   2845:                write_2(ea, data);
                   2846:        }
                   2847: }
                   2848: 
                   2849: // %0101_qqq010_mmmrrr d.m+-rxw.. 034  ADDQ.L #qqq,<ea>
                   2850: // %0101_qqq010_001yyy .a........ 034  ADDQ.L #qqq,Ay
                   2851: OP_DEF(addq_l)
                   2852: {
                   2853:        uint n = ir & 0x3f;
                   2854: 
                   2855:        uint32 src = RegIRX;
                   2856:        src = (src == 0) ? 8 : src;
                   2857:        if (n < 8) {
                   2858:                // ADDQ.L #qqq,Dn
1.1.1.2   root     2859:                CYCLE3(addq_rn);
1.1       root     2860:                reg.D[n] = ACC.add_32(src, reg.D[n]);
                   2861:        } else if (n < 16) {
                   2862:                // ADDQ.L #qqq,An
                   2863:                // フラグは変化しない
1.1.1.2   root     2864:                CYCLE3(addq_rn);
1.1       root     2865:                reg.R[n] += src;
                   2866:        } else {
                   2867:                // ADDQ.L #qqq,<ea>
1.1.1.2   root     2868:                CYCLE3(addq_ea);
1.1       root     2869:                uint32 ea = cea_data_4();
                   2870:                uint32 data = read_4(ea);
                   2871:                data = ACC.add_32(src, data);
                   2872:                write_4(ea, data);
                   2873:        }
                   2874: }
                   2875: 
                   2876: // TRAPcc の共通部分。
                   2877: void
                   2878: MPU680x0Device::ops_trapcc(uint cond)
                   2879: {
                   2880:        // 条件成立すれば例外。成立しなければ何もしない。
                   2881:        // いずれの場合もオペランドありの形態なら事前に読み飛ばしておくこと。
                   2882:        if (CCR.Cond(cond)) {
1.1.1.2   root     2883:                CYCLE3(trapcc_excep);
1.1       root     2884:                Exception(M68K::EXCEP_TRAPV);
                   2885:        } else {
                   2886:                // サイクルを消費するだけ
1.1.1.2   root     2887:                CYCLE3(trapcc);
1.1       root     2888:        }
                   2889: }
                   2890: 
                   2891: // %0101_cccc11_mmmrrr d.m+-rxw.. 034  Scc.B <ea>
                   2892: // %0101_cccc11_001yyy .......... 034  DBcc.W Dy,<label>
                   2893: // %0101_cccc11_111010 .......... -34  TRAPcc.W #<imm>
                   2894: // %0101_cccc11_111011 .......... -34  TRAPcc.L #<imm>
                   2895: // %0101_cccc11_111100 .......... -34  TRAPcc
                   2896: // %0101_000111_001yyy .......... 034  DBRA.W Dy,<label>
                   2897: OP_DEF(scc)
                   2898: {
                   2899:        uint n = ir & 0x3f;
                   2900:        uint cond = (ir >> 8) & 0x0f;
                   2901: 
                   2902:        switch (n) {
                   2903:         case 0b000000 ... 0b000111:    // Scc.B Dn
1.1.1.2   root     2904:                CYCLE3(scc_dn);
1.1       root     2905:                if (CCR.Cond(cond)) {
                   2906:                        RegDY |= 0xff;
                   2907:                } else {
                   2908:                        RegDY &= ~0xff;
                   2909:                }
                   2910:                return;
                   2911: 
                   2912:         case 0b001000 ... 0b001111:    // DBcc.W Dy,<label>
                   2913:                if (CCR.Cond(cond)) {
                   2914:                        // 真なら何もしない。disp を読み飛ばして次へ。
1.1.1.2   root     2915:                        CYCLE3(dbcc_nop);
1.1       root     2916:                        fetch_2();
                   2917:                } else {
                   2918:                        // 偽の場合
                   2919: 
                   2920:                        // Dy.W を減算して(下位ワードに)書き戻し、Dy.W が -1 だったら
                   2921:                        // ループ終了。だが最適化のため、減算前の Dy.W が 0 の時は
                   2922:                        // 下位ワードを 0xffff にしてループ終了、そうでなければ Dy.L を
                   2923:                        // 減算するだけでいいはず。
                   2924: 
                   2925:                        uint16 data = RegDY;
                   2926:                        if (data == 0) {
                   2927:                                // ループ終了。disp を読み飛ばす
1.1.1.2   root     2928:                                CYCLE3(dbcc_done);
1.1       root     2929:                                RegDY |= 0x0000ffff;
                   2930:                                fetch_2();
                   2931:                        } else {
1.1.1.2   root     2932:                                CYCLE3(dbcc_jmp);
1.1       root     2933:                                RegDY--;
                   2934:                                uint32 origin = reg.pc;
                   2935:                                int32 disp = (int32)(int16)fetch_2();
                   2936:                                Jump(origin + disp);
                   2937:                        }
                   2938:                }
                   2939:                return;
                   2940: 
                   2941:         case 0b010000 ... 0b010111:    // Scc.B <ea>
                   2942:         case 0b011000 ... 0b011111:    // Scc.B <ea>
                   2943:         case 0b100000 ... 0b100111:    // Scc.B <ea>
                   2944:         case 0b101000 ... 0b101111:    // Scc.B <ea>
                   2945:         case 0b110000 ... 0b110111:    // Scc.B <ea>
                   2946:         case 0b111000:                                 // Scc.B <ea>
                   2947:         case 0b111001:                                 // Scc.B <ea>
                   2948:         {
1.1.1.2   root     2949:                CYCLE3(scc_ea);
1.1       root     2950:                // 条件成立可否に関わらず EA は取得しないといけない
                   2951:                uint32 ea = cea_data_1();
                   2952:                uint32 data;
                   2953:                if (CCR.Cond(cond)) {
                   2954:                        data = 0xff;
                   2955:                } else {
                   2956:                        data = 0;
                   2957:                }
                   2958:                write_1(ea, data);
                   2959:                return;
                   2960:         }
                   2961: 
                   2962:         case 0b111010:         // TRAPcc.W #<imm>
                   2963:                // オペランドなしTRAPccに比べてすべてのケースで2サイクル多い
1.1.1.2   root     2964:                CYCLE3(trapcc_w_inc);
1.1       root     2965:                fetch_2();
                   2966:                ops_trapcc(cond);
                   2967:                return;
                   2968: 
                   2969:         case 0b111011:         // TRAPcc.L #<imm>
                   2970:                // オペランドなしTRAPccに比べてすべてのケースで4サイクル多い
1.1.1.2   root     2971:                CYCLE3(trapcc_l_inc);
1.1       root     2972:                fetch_4();
                   2973:                ops_trapcc(cond);
                   2974:                return;
                   2975: 
                   2976:         case 0b111100:         // TRAPcc
                   2977:                ops_trapcc(cond);
                   2978:                return;
                   2979: 
                   2980:         default:
1.1.1.3 ! root     2981:                break;
1.1       root     2982:        }
1.1.1.3 ! root     2983:        OP_FUNC(illegal);
1.1       root     2984: }
                   2985: 
                   2986: // %0101_qqq100_mmmrrr d.m+-rxw.. 034  SUBQ.B #qqq,<ea>
                   2987: OP_DEF(subq_b)
                   2988: {
                   2989:        uint n = ir & 0x3f;
                   2990: 
                   2991:        uint32 src = RegIRX;
                   2992:        src = (src == 0) ? 8 : src;
                   2993:        if (n < 8) {
                   2994:                // SUBQ.B #qqq,Dn
1.1.1.2   root     2995:                CYCLE3(subq_rn);
1.1       root     2996:                uint32 data = ACC.sub_8(src, reg.D[n] & 0xff);
                   2997:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
                   2998:        } else {
                   2999:                // SUBQ.B #qqq,<ea>
1.1.1.2   root     3000:                CYCLE3(subq_ea);
1.1       root     3001:                uint32 ea = cea_data_1();
                   3002:                uint32 data = read_1(ea);
                   3003:                data = ACC.sub_8(src, data);
                   3004:                write_1(ea, data);
                   3005:        }
                   3006: }
                   3007: 
                   3008: // %0101_qqq101_mmmrrr d.m+-rxw.. 034  SUBQ.W #qqq,<ea>
                   3009: // %0101_qqq101_001yyy .a........ 034  SUBQ.W #qqq,Ay (.Lと等価)
                   3010: OP_DEF(subq_w)
                   3011: {
                   3012:        uint n = ir & 0x3f;
                   3013: 
                   3014:        uint32 src = RegIRX;
                   3015:        src = (src == 0) ? 8 : src;
                   3016:        if (n < 8) {
                   3017:                // SUBQ.W #qqq,Dn
1.1.1.2   root     3018:                CYCLE3(subq_rn);
1.1       root     3019:                uint32 data = ACC.sub_16(src, reg.D[n] & 0xffff);
                   3020:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
                   3021:        } else if (n < 16) {
                   3022:                // SUBQ.W #qqq,An は SUBQ.L と等価
                   3023:                // フラグは変化しない
1.1.1.2   root     3024:                CYCLE3(subq_rn);
1.1       root     3025:                reg.R[n] -= src;
                   3026:        } else {
                   3027:                // SUBQ.W #qqq,<ea>
1.1.1.2   root     3028:                CYCLE3(subq_ea);
1.1       root     3029:                uint32 ea = cea_data_2();
                   3030:                uint32 data = read_2(ea);
                   3031:                data = ACC.sub_16(src, data);
                   3032:                write_2(ea, data);
                   3033:        }
                   3034: }
                   3035: 
                   3036: // %0101_qqq110_mmmrrr d.m+-rxw.. 034  SUBQ.L #qqq,<ea>
                   3037: // %0101_qqq110_001yyy .a........ 034  SUBQ.L #qqq,Ay
                   3038: OP_DEF(subq_l)
                   3039: {
                   3040:        uint n = ir & 0x3f;
                   3041: 
                   3042:        uint32 src = RegIRX;
                   3043:        src = (src == 0) ? 8 : src;
                   3044:        if (n < 8) {
                   3045:                // SUBQ.L #qqq,Dn
1.1.1.2   root     3046:                CYCLE3(subq_rn);
1.1       root     3047:                reg.D[n] = ACC.sub_32(src, reg.D[n]);
                   3048:        } else if (n < 16) {
                   3049:                // SUBQ.L #qqq,An
                   3050:                // フラグは変化しない
1.1.1.2   root     3051:                CYCLE3(subq_rn);
1.1       root     3052:                reg.R[n] -= src;
                   3053:        } else {
                   3054:                // SUBQ.L #qqq,<ea>
1.1.1.2   root     3055:                CYCLE3(subq_ea);
1.1       root     3056:                uint32 ea = cea_data_4();
                   3057:                uint32 data = read_4(ea);
                   3058:                data = ACC.sub_32(src, data);
                   3059:                write_4(ea, data);
                   3060:        }
                   3061: }
                   3062: 
                   3063: inline void
                   3064: MPU680x0Device::ops_bra()
                   3065: {
1.1.1.2   root     3066:        CYCLE3(bra);
1.1       root     3067: 
                   3068:        uint32 origin = reg.pc;
                   3069:        int32 disp = (int32)(int8)(ir & 0xff);
                   3070:        if (disp == -1) {
                   3071:                // Bcc.L
                   3072:                disp = (int32)fetch_4();
                   3073:        } else if (disp == 0) {
                   3074:                // Bcc.W
                   3075:                disp = (int32)(int16)fetch_2();
                   3076:        }
                   3077:        Jump(origin + disp);
                   3078: }
                   3079: 
                   3080: // %0110_0000nn_nnnnnn .......... 034  BRA.B <label>
                   3081: // %0110_000000_000000 .......... 034  BRA.W <label>
                   3082: // %0110_000011_111111 .......... -34  BRA.L <label>
                   3083: OP_DEF(bra)
                   3084: {
                   3085:        ops_bra();
                   3086: }
                   3087: 
                   3088: // %0110_0001nn_nnnnnn .......... 034  BSR.B <label>
                   3089: // %0110_000100_000000 .......... 034  BSR.W <label>
                   3090: // %0110_000111_111111 .......... -34  BSR.L <label>
                   3091: OP_DEF(bsr)
                   3092: {
1.1.1.2   root     3093:        CYCLE3(bsr);
1.1       root     3094:        uint32 origin = reg.pc;
                   3095:        int32 disp = (int32)(int8)(ir & 0xff);
                   3096:        if (disp == -1) {
                   3097:                // BSR.L <label>
                   3098:                disp = (int32)fetch_4();
                   3099:        } else if (disp == 0) {
                   3100:                // BSR.W <label>
                   3101:                disp = (int32)(int16)fetch_2();
                   3102:        }
                   3103: 
                   3104:        // ページフォルトに備えて保存する。
                   3105:        save_reg_pd(7);
                   3106:        push_4(reg.pc);
                   3107:        Jump(origin + disp);
                   3108: }
                   3109: 
                   3110: // %0110_ccccnn_nnnnnn .......... 034  Bcc.B <label>
                   3111: // %0110_cccc00_000000 .......... 034  Bcc.W <label>
                   3112: // %0110_cccc11_111111 .......... -34  Bcc.L <label>
                   3113: OP_DEF(bcc)
                   3114: {
                   3115:        // ブランチするかどうかでサイクルが変わるので先に条件を調べる
                   3116:        uint cond = (ir >> 8) & 0x0f;
                   3117:        if (CCR.Cond(cond)) {
                   3118:                // Bcc (taken)
                   3119:                ops_bra();
                   3120:        } else {
                   3121:                int32 disp = (int32)(int8)(ir & 0xff);
                   3122:                if (disp == -1) {
                   3123:                        // Bcc.L (not taken)
1.1.1.2   root     3124:                        CYCLE3(bcc_l_not);
1.1       root     3125:                        fetch_4();
                   3126:                } else if (disp == 0) {
                   3127:                        // Bcc.W (not taken)
1.1.1.2   root     3128:                        CYCLE3(bcc_w_not);
1.1       root     3129:                        fetch_2();
                   3130:                } else {
                   3131:                        // Bcc.B (not taken)
1.1.1.2   root     3132:                        CYCLE3(bcc_b_not);
1.1       root     3133:                }
                   3134:        }
                   3135: }
                   3136: 
                   3137: // %0111_xxx0nn_nnnnnn .......... 034  MOVEQ.L #<imm>,Dx
                   3138: OP_DEF(moveq)
                   3139: {
1.1.1.2   root     3140:        CYCLE3(moveq);
1.1       root     3141:        RegDX = (int32)(int8)(ir & 0xff);
                   3142:        ACC.move_32(RegDX);
                   3143: }
                   3144: 
                   3145: // %1000_xxx000_mmmrrr d.m+-rxwpi 034  OR.B <ea>,Dx
                   3146: OP_DEF(or_b_ea_dn)
                   3147: {
                   3148:        uint n = ir & 0x3f;
                   3149: 
1.1.1.2   root     3150:        CYCLE3(or_ea_dn);
1.1       root     3151:        uint x = RegIRX;
                   3152:        if (n < 8) {
                   3153:                // OR.B Dn,Dx
                   3154:                uint32 data = (reg.D[x] | reg.D[n]) & 0xff;
                   3155:                ACC.move_8(data);
                   3156:                reg.D[x] = (reg.D[x] & 0xffffff00) | data;
                   3157:        } else {
                   3158:                // OR.B <ea>,Dx
                   3159:                uint32 src = fea_data_1();
                   3160:                uint32 data = (reg.D[x] | src) & 0xff;
                   3161:                ACC.move_8(data);
                   3162:                reg.D[x] = (reg.D[x] & 0xffffff00) | data;
                   3163:        }
                   3164: }
                   3165: 
                   3166: // %1000_xxx001_mmmrrr d.m+-rxwpi 034  OR.W <ea>,Dx
                   3167: OP_DEF(or_w_ea_dn)
                   3168: {
                   3169:        uint n = ir & 0x3f;
                   3170: 
1.1.1.2   root     3171:        CYCLE3(or_ea_dn);
1.1       root     3172:        uint x = RegIRX;
                   3173:        if (n < 8) {
                   3174:                // OR.W Dn,Dx
                   3175:                uint32 data = (reg.D[x] | reg.D[n]) & 0xffff;
                   3176:                ACC.move_16(data);
                   3177:                reg.D[x] = (reg.D[x] & 0xffff0000) | data;
                   3178:        } else {
                   3179:                // OR.W <ea>,Dx
                   3180:                uint32 src = fea_data_2();
                   3181:                uint32 data = (reg.D[x] | src) & 0xffff;
                   3182:                ACC.move_16(data);
                   3183:                reg.D[x] = (reg.D[x] & 0xffff0000) | data;
                   3184:        }
                   3185: }
                   3186: 
                   3187: // %1000_xxx010_mmmrrr d.m+-rxwpi 034  OR.L <ea>,Dx
                   3188: OP_DEF(or_l_ea_dn)
                   3189: {
                   3190:        uint n = ir & 0x3f;
                   3191: 
1.1.1.2   root     3192:        CYCLE3(or_ea_dn);
1.1       root     3193:        uint x = RegIRX;
                   3194:        if (n < 8) {
                   3195:                // OR.L Dn,Dx
                   3196:                reg.D[x] |= reg.D[n];
                   3197:                ACC.move_32(reg.D[x]);
                   3198:        } else {
                   3199:                // OR.L <ea>,Dx
                   3200:                uint32 src = fea_data_4();
                   3201:                uint32 data = reg.D[x] | src;
                   3202:                ACC.move_32(data);
                   3203:                reg.D[x] = data;
                   3204:        }
                   3205: }
                   3206: 
                   3207: // %1000_xxx011_mmmrrr d.m+-rxwpi 034  DIVU.W <ea>,Dx
                   3208: OP_DEF(divu_w)
                   3209: {
1.1.1.2   root     3210:        CYCLE3(divu_w_max);
1.1       root     3211: 
                   3212:        uint16 src = fea_data_2();
                   3213:        uint32 dst = RegDX;
                   3214: 
                   3215:        if (src == 0) {
                   3216:                // ゼロ除算の場合、
                   3217:                // X は変化しない
                   3218:                // C は常にクリア
                   3219:                // N,Z,V は未定義
                   3220:                CCR.SetC(false);
                   3221:                Exception(M68K::EXCEP_ZERODIV);
                   3222:                return;
                   3223:        }
                   3224: 
                   3225:        uint32 quo = dst / src;
                   3226:        uint32 rem = dst % src;
                   3227:        if (quo > 0xffff) {
                   3228:                // オーバーフローの場合、
                   3229:                // X は変化しない
                   3230:                // N,Z は未定義
                   3231:                // V はセット
                   3232:                // C は常にクリア
                   3233:                CCR.SetV(true);
                   3234:                CCR.SetC(false);
                   3235:                return;
                   3236:        }
                   3237: 
                   3238:        // 正常の場合、
                   3239:        // X は変化しない
                   3240:        // V, C はクリア
                   3241:        // N, Z は quo の結果。
                   3242:        RegDX = (rem << 16) | quo;
                   3243:        ACC.move_16(quo);
                   3244: }
                   3245: 
                   3246: // %1000_xxx100_mmmrrr ..m+-rxw.. 034  OR.B Dx,<ea>
                   3247: // %1000_xxx100_000yyy .......... 034  SBCD.B Dy,Dx
                   3248: // %1000_xxx100_001yyy .......... 034  SBCD.B -(Ay),-(Ax)
                   3249: OP_DEF(or_b_dn_ea)
                   3250: {
                   3251:        uint n = ir & 0x3f;
                   3252: 
                   3253:        if (n < 8) {
                   3254:                // SBCD.B Dy,Dx
1.1.1.2   root     3255:                CYCLE3(sbcd_dn);
1.1       root     3256:                uint32 src = RegDY & 0xff;
                   3257:                uint32 dst = RegDX & 0xff;
                   3258:                dst = ACC.sbcd_8(src, dst);
                   3259:                RegDX &= 0xffffff00;
                   3260:                RegDX |= dst;
                   3261:        } else if (n < 16) {
                   3262:                // SBCD.B -(Ay),-(Ax)
1.1.1.2   root     3263:                CYCLE3(sbcd_an);
1.1       root     3264:                save_reg_pd_if(RegIRY);
                   3265:                save_reg_pd_if(RegIRX);
                   3266:                uint32 srcea = internal_ea_anpd_1(RegIRY);
                   3267:                uint32 dstea = internal_ea_anpd_1(RegIRX);
                   3268:                uint32 src = read_1(srcea);
                   3269:                uint32 dst = read_1(dstea);
                   3270:                dst = ACC.sbcd_8(src, dst);
                   3271:                write_1(dstea, dst);
                   3272:        } else {
                   3273:                // OR.B Dx,<ea>
1.1.1.2   root     3274:                CYCLE3(or_dn_ea);
1.1       root     3275:                uint32 ea = cea_data_1();
                   3276:                uint8 data = read_1(ea);
                   3277:                data |= RegDX;
                   3278:                ACC.move_8(data);
                   3279:                write_1(ea, data);
                   3280:        }
                   3281: }
                   3282: 
                   3283: // %1000_xxx101_mmmrrr ..m+-rxw.. 034  OR.W Dx,<ea>
                   3284: // %1000_xxx101_000yyy .......... -34  PACK Dy,Dx,#<imm>
                   3285: // %1000_xxx101_001yyy .......... -34  PACK -(Ay),-(Ax),#<imm>
                   3286: OP_DEF(or_w_dn_ea)
                   3287: {
                   3288:        uint n = ir & 0x3f;
                   3289: 
                   3290:        if (n < 8) {
                   3291:                // PACK Dy,Dx,#<imm>
1.1.1.2   root     3292:                CYCLE3(pack_dn);
1.1       root     3293:                uint32 imm = fetch_2();
                   3294:                uint32 src = RegDY + imm;
                   3295:                RegDX = (RegDX & 0xffffff00) | ((src >> 4) & 0x00f0) | (src & 0x000f);
                   3296:        } else if (n < 16) {
                   3297:                // PACK -(Ay),-(Ax),#<imm>
1.1.1.2   root     3298:                CYCLE3(pack_an);
1.1       root     3299:                uint32 imm = fetch_2();
                   3300:                save_reg_pd(RegIRY);
1.1.1.3 ! root     3301:                uint32 srcea = internal_ea_anpd_2(RegIRY);
        !          3302:                uint32 src = read_2(srcea);
1.1       root     3303:                src += imm;
                   3304:                uint32 dst = ((src >> 4) & 0x00f0) | (src & 0x000f);
                   3305:                save_reg_pd_if(RegIRX);
                   3306:                uint32 dstea = internal_ea_anpd_1(RegIRX);
                   3307:                write_1(dstea, dst);
                   3308:        } else {
                   3309:                // OR.W Dx,<ea>
1.1.1.2   root     3310:                CYCLE3(or_dn_ea);
1.1       root     3311:                uint32 ea = cea_data_2();
                   3312:                uint16 data = read_2(ea);
                   3313:                data |= RegDX;
                   3314:                ACC.move_16(data);
                   3315:                write_2(ea, data);
                   3316:        }
                   3317: }
                   3318: 
                   3319: // %1000_xxx110_mmmrrr ..m+-rxw.. 034  OR.L Dx,<ea>
                   3320: // %1000_xxx110_000yyy .......... -34  UNPK Dy,Dx,#<imm>
                   3321: // %1000_xxx110_001yyy .......... -34  UNPK -(Ay),-(Ax),#<imm>
                   3322: OP_DEF(or_l_dn_ea)
                   3323: {
                   3324:        uint n = ir & 0x3f;
                   3325: 
                   3326:        if (n < 8) {
                   3327:                // UNPK Dy,Dx,#<imm>
1.1.1.2   root     3328:                CYCLE3(unpk_dn);
1.1       root     3329:                uint32 imm = fetch_2();
                   3330:                uint16 src = RegDY;
                   3331:                src = ((src & 0x00f0) << 4) | (src & 0x000f);
                   3332:                src += imm;
                   3333:                RegDX = (RegDX & 0xffff0000) | src;
                   3334:        } else if (n < 16) {
                   3335:                // UNPK -(Ay),-(Ax),#<imm>
1.1.1.2   root     3336:                CYCLE3(unpk_an);
1.1       root     3337:                uint32 imm = fetch_2();
                   3338:                save_reg_pd(RegIRY);
                   3339:                uint32 srcea = internal_ea_anpd_1(RegIRY);
                   3340:                uint16 src = read_1(srcea);
                   3341:                src = ((src & 0x00f0) << 4) | (src & 0x000f);
                   3342:                src += imm;
                   3343:                save_reg_pd_if(RegIRX);
1.1.1.3 ! root     3344:                uint32 dstea = internal_ea_anpd_2(RegIRX);
        !          3345:                write_2(dstea, src);
1.1       root     3346:        } else {
                   3347:                // OR.L Dx,<ea>
1.1.1.2   root     3348:                CYCLE3(or_dn_ea);
1.1       root     3349:                uint32 ea = cea_data_4();
                   3350:                uint32 data = read_4(ea);
                   3351:                data |= RegDX;
                   3352:                ACC.move_32(data);
                   3353:                write_4(ea, data);
                   3354:        }
                   3355: }
                   3356: 
                   3357: // %1000_xxx111_mmmrrr d.m+-rxwpi 034  DIVS.W <ea>,Dx
                   3358: OP_DEF(divs_w)
                   3359: {
1.1.1.2   root     3360:        CYCLE3(divs_w_max);
1.1       root     3361: 
                   3362:        uint16 src = fea_data_2();
                   3363:        uint32 dst = RegDX;
                   3364: 
                   3365:        if (src == 0) {
                   3366:                // ゼロ除算の場合、
                   3367:                // X は変化しない
                   3368:                // C は常にクリア
                   3369:                // N,Z,V は未定義
                   3370:                CCR.SetC(false);
                   3371:                Exception(M68K::EXCEP_ZERODIV);
                   3372:                return;
                   3373:        }
                   3374: 
                   3375:        // ホストでオーバーフローが起きるのはこのケースのみ
                   3376:        if (dst == 0x80000000 && src == 0xffff) {
                   3377:                // オーバーフローの場合、
                   3378:                // X は変化しない
                   3379:                // N,Z は未定義
                   3380:                // V はセット
                   3381:                // C は常にクリア
                   3382:                CCR.SetV(true);
                   3383:                CCR.SetC(false);
                   3384:                return;
                   3385:        }
                   3386: 
                   3387:        int32 squo = (int32)dst / (int32)(int16)src;
                   3388:        int32 srem = (int32)dst % (int32)(int16)src;
                   3389:        if ((int16)squo != squo) {
                   3390:                // オーバーフローの場合
                   3391:                CCR.SetV(true);
                   3392:                CCR.SetC(false);
                   3393:                return;
                   3394:        }
                   3395:        // 正常の場合、
                   3396:        // X は変化しない
                   3397:        // V, C はクリア
                   3398:        // N, Z は quo の結果。
                   3399:        uint32 quo = (uint32)squo & 0xffff;
                   3400:        uint32 rem = (uint32)srem & 0xffff;
                   3401:        RegDX = (rem << 16) | quo;
                   3402:        ACC.move_16(quo);
                   3403: }
                   3404: 
                   3405: // %1001_xxx000_mmmrrr dam+-rxwpi 034  SUB.B <ea>,Dx
                   3406: OP_DEF(sub_b_ea_dn)
                   3407: {
1.1.1.2   root     3408:        CYCLE3(sub_ea_dn);
1.1       root     3409:        uint32 src = fea_all_1();
                   3410:        uint32 data = ACC.sub_8(src, RegDX & 0xff);
                   3411:        RegDX = (RegDX & 0xffffff00) | data;
                   3412: }
                   3413: 
                   3414: // %1001_xxx001_mmmrrr dam+-rxwpi 034  SUB.W <ea>,Dx
                   3415: OP_DEF(sub_w_ea_dn)
                   3416: {
1.1.1.2   root     3417:        CYCLE3(sub_ea_dn);
1.1       root     3418:        uint32 src = fea_all_2();
                   3419:        uint32 data = ACC.sub_16(src, RegDX & 0xffff);
                   3420:        RegDX = (RegDX & 0xffff0000) | data;
                   3421: }
                   3422: 
                   3423: // %1001_xxx010_mmmrrr dam+-rxwpi 034  SUB.L <ea>,Dx
                   3424: OP_DEF(sub_l_ea_dn)
                   3425: {
1.1.1.2   root     3426:        CYCLE3(sub_ea_dn);
1.1       root     3427:        uint32 src = fea_all_4();
                   3428:        RegDX = ACC.sub_32(src, RegDX);
                   3429: }
                   3430: 
                   3431: // %1001_xxx011_mmmrrr dam+-rxwpi 034  SUBA.W <ea>,Ax
                   3432: OP_DEF(suba_w)
                   3433: {
1.1.1.2   root     3434:        CYCLE3(suba_w);
1.1       root     3435:        uint32 src = (int32)(int16)fea_all_2();
                   3436:        RegAX -= src;
                   3437: }
                   3438: 
                   3439: // %1001_xxx100_mmmrrr ..m+-rxw.. 034  SUB.B Dx,<ea>
                   3440: // %1001_xxx100_000yyy .......... 034  SUBX.B Dy,Dx
                   3441: // %1001_xxx100_001yyy .......... 034  SUBX.B -(Ay),-(Ax)
                   3442: OP_DEF(sub_b_dn_ea)
                   3443: {
                   3444:        uint n = ir & 0x3f;
                   3445: 
                   3446:        if (n < 8) {
                   3447:                // SUBX.B Dy,Dx
1.1.1.2   root     3448:                CYCLE3(subx_dn);
1.1       root     3449:                uint32 src = RegDY & 0xff;
                   3450:                uint32 dst = RegDX & 0xff;
                   3451:                dst = ACC.subx_8(src, dst);
                   3452:                RegDX = (RegDX & 0xffffff00) | dst;
                   3453:        } else if (n < 16) {
                   3454:                // SUBX.B -(Ay),-(Ax)
1.1.1.2   root     3455:                CYCLE3(subx_an);
1.1       root     3456:                save_reg_pd_if(RegIRY);
                   3457:                save_reg_pd_if(RegIRX);
                   3458:                uint32 srcea = internal_ea_anpd_1(RegIRY);
                   3459:                uint32 dstea = internal_ea_anpd_1(RegIRX);
                   3460:                uint32 src = read_1(srcea);
                   3461:                uint32 dst = read_1(dstea);
                   3462:                dst = ACC.subx_8(src, dst);
                   3463:                write_1(dstea, dst);
                   3464:        } else {
                   3465:                // SUB.B Dx,<ea>
1.1.1.2   root     3466:                CYCLE3(sub_dn_ea);
1.1       root     3467:                uint32 ea = cea_data_1();
                   3468:                uint32 data = read_1(ea);
                   3469:                data = ACC.sub_8(RegDX & 0xff, data);
                   3470:                write_1(ea, data);
                   3471:        }
                   3472: }
                   3473: 
                   3474: // %1001_xxx101_mmmrrr ..m+-rxw.. 034  SUB.W Dx,<ea>
                   3475: // %1001_xxx101_000yyy .......... 034  SUBX.W Dy,Dx
                   3476: // %1001_xxx101_001yyy .......... 034  SUBX.W -(Ay),-(Ax)
                   3477: OP_DEF(sub_w_dn_ea)
                   3478: {
                   3479:        uint n = ir & 0x3f;
                   3480: 
                   3481:        if (n < 8) {
                   3482:                // SUBX.W Dy,Dx
1.1.1.2   root     3483:                CYCLE3(subx_dn);
1.1       root     3484:                uint32 src = RegDY & 0xffff;
                   3485:                uint32 dst = RegDX & 0xffff;
                   3486:                dst = ACC.subx_16(src, dst);
                   3487:                RegDX = (RegDX & 0xffff0000) | dst;
                   3488:        } else if (n < 16) {
                   3489:                // SUBX.W -(Ay),-(Ax)
1.1.1.2   root     3490:                CYCLE3(subx_an);
1.1       root     3491:                save_reg_pd_if(RegIRY);
                   3492:                save_reg_pd_if(RegIRX);
                   3493:                uint32 srcea = internal_ea_anpd_2(RegIRY);
                   3494:                uint32 dstea = internal_ea_anpd_2(RegIRX);
                   3495:                uint32 src = read_2(srcea);
                   3496:                uint32 dst = read_2(dstea);
                   3497:                dst = ACC.subx_16(src, dst);
                   3498:                write_2(dstea, dst);
                   3499:        } else {
                   3500:                // SUB.W Dx,<ea>
1.1.1.2   root     3501:                CYCLE3(sub_dn_ea);
1.1       root     3502:                uint32 ea = cea_data_2();
                   3503:                uint32 data = read_2(ea);
                   3504:                data = ACC.sub_16(RegDX & 0xffff, data);
                   3505:                write_2(ea, data);
                   3506:        }
                   3507: }
                   3508: 
                   3509: // %1001_xxx110_mmmrrr ..m+-rxw.. 034  SUB.L Dx,<ea>
                   3510: // %1001_xxx110_000yyy .......... 034  SUBX.L Dy,Dx
                   3511: // %1001_xxx110_001yyy .......... 034  SUBX.L -(Ay),-(Ax)
                   3512: OP_DEF(sub_l_dn_ea)
                   3513: {
                   3514:        uint n = ir & 0x3f;
                   3515: 
                   3516:        if (n < 8) {
                   3517:                // SUBX.L Dy,Dx
1.1.1.2   root     3518:                CYCLE3(subx_dn);
1.1       root     3519:                uint32 src = RegDY;
                   3520:                uint32 dst = RegDX;
                   3521:                RegDX = ACC.subx_32(src, dst);
                   3522:        } else if (n < 16) {
                   3523:                // SUBX.L -(Ay),-(Ax)
1.1.1.2   root     3524:                CYCLE3(subx_an);
1.1       root     3525:                save_reg_pd_if(RegIRY);
                   3526:                save_reg_pd_if(RegIRX);
                   3527:                uint32 srcea = internal_ea_anpd_4(RegIRY);
                   3528:                uint32 dstea = internal_ea_anpd_4(RegIRX);
                   3529:                uint32 src = read_4(srcea);
                   3530:                uint32 dst = read_4(dstea);
                   3531:                dst = ACC.subx_32(src, dst);
                   3532:                write_4(dstea, dst);
                   3533:        } else {
                   3534:                // SUB.L Dx,<ea>
1.1.1.2   root     3535:                CYCLE3(sub_dn_ea);
1.1       root     3536:                uint32 ea = cea_data_4();
                   3537:                uint32 data = read_4(ea);
                   3538:                data = ACC.sub_32(RegDX, data);
                   3539:                write_4(ea, data);
                   3540:        }
                   3541: }
                   3542: 
                   3543: // %1001_xxx111_mmmrrr dam+-rxwpi 034  SUBA.L <ea>,Ax
                   3544: OP_DEF(suba_l)
                   3545: {
1.1.1.2   root     3546:        CYCLE3(suba_l);
1.1       root     3547:        uint32 src = fea_all_4();
                   3548:        RegAX -= src;
                   3549: }
                   3550: 
                   3551: // %1010_nnnnnn_nnnnnn .......... 034  A-Line
                   3552: OP_DEF(aline)
                   3553: {
1.1.1.2   root     3554:        CYCLE3(aline);
1.1       root     3555:        if (aline_callback) {
                   3556:                if (aline_callback(this, aline_arg)) {
                   3557:                        return;
                   3558:                }
                   3559:        }
                   3560:        // A系列命令例外
                   3561:        Exception(M68K::EXCEP_ALINE);
                   3562: }
                   3563: 
                   3564: // %1011_xxx000_mmmrrr d.m+-rxwpi 034  CMP.B <ea>,Dx
                   3565: OP_DEF(cmp_b)
                   3566: {
1.1.1.2   root     3567:        CYCLE3(cmp);
1.1       root     3568:        uint32 src = fea_all_1();
                   3569:        uint32 dst = RegDX & 0xff;
                   3570:        ACC.cmp_8(src, dst);
                   3571: }
                   3572: 
                   3573: // %1011_xxx001_mmmrrr d.m+-rxwpi 034  CMP.W <ea>,Dx
                   3574: OP_DEF(cmp_w)
                   3575: {
1.1.1.2   root     3576:        CYCLE3(cmp);
1.1       root     3577:        uint32 src = fea_all_2();
                   3578:        uint32 dst = RegDX & 0xffff;
                   3579:        ACC.cmp_16(src, dst);
                   3580: }
                   3581: 
                   3582: // %1011_xxx010_mmmrrr d.m+-rxwpi 034  CMP.L <ea>,Dx
                   3583: OP_DEF(cmp_l)
                   3584: {
1.1.1.2   root     3585:        CYCLE3(cmp);
1.1       root     3586:        uint32 src = fea_all_4();
                   3587:        ACC.cmp_32(src, RegDX);
                   3588: }
                   3589: 
                   3590: // %1011_xxx011_mmmrrr dam+-rxwpi 034  CMPA.W <ea>,Ax
                   3591: OP_DEF(cmpa_w)
                   3592: {
1.1.1.2   root     3593:        CYCLE3(cmpa);
1.1       root     3594:        uint32 src = (uint32)(int32)(int16)fea_all_2();
                   3595:        ACC.cmp_32(src, RegAX);
                   3596: }
                   3597: 
                   3598: // %1011_xxx100_mmmrrr d.m+-rxw.. 034  EOR.B Dx,<ea>
                   3599: // %1011_xxx100_001yyy .......... 034  CMPM.B (Ay)+,(Ax)+
                   3600: OP_DEF(eor_b)
                   3601: {
                   3602:        uint n = ir & 0x3f;
                   3603: 
                   3604:        if (n < 8) {
                   3605:                // EOR.B Dx,Dy
1.1.1.2   root     3606:                CYCLE3(eor_dn_dn);
1.1       root     3607:                uint32 data = (reg.D[n] ^ RegDX) & 0xff;
                   3608:                reg.D[n] = (reg.D[n] & 0xffffff00) | data;
                   3609:                ACC.move_8(data);
                   3610:        } else if (n < 16) {
                   3611:                // CMPM.B (Ay)+,(Ax)+
1.1.1.2   root     3612:                CYCLE3(cmpm);
1.1       root     3613:                save_reg_pi_if(RegIRY);
                   3614:                save_reg_pi_if(RegIRX);
                   3615:                uint32 srcea = internal_ea_anpi_1(RegIRY);
                   3616:                uint32 dstea = internal_ea_anpi_1(RegIRX);
                   3617:                uint32 src = read_1(srcea);
                   3618:                uint32 dst = read_1(dstea);
                   3619:                ACC.cmp_8(src, dst);
                   3620:        } else {
                   3621:                // EOR.B Dx,<ea>
1.1.1.2   root     3622:                CYCLE3(eor_dn_ea);
1.1       root     3623:                uint32 ea = cea_data_1();
                   3624:                uint32 data = read_1(ea);
                   3625:                data ^= (RegDX & 0xff);
                   3626:                ACC.move_8(data);
1.1.1.3 ! root     3627:                write_1(ea, data);
1.1       root     3628:        }
                   3629: }
                   3630: 
                   3631: // %1011_xxx101_mmmrrr d.m+-rxw.. 034  EOR.W Dx,<ea>
                   3632: // %1011_xxx101_001yyy .......... 034  CMPM.W (Ay)+,(Ax)+
                   3633: OP_DEF(eor_w)
                   3634: {
                   3635:        uint n = ir & 0x3f;
                   3636: 
                   3637:        if (n < 8) {
                   3638:                // EOR.W Dx,Dy
1.1.1.2   root     3639:                CYCLE3(eor_dn_dn);
1.1       root     3640:                uint32 data = (reg.D[n] ^ RegDX) & 0xffff;
                   3641:                reg.D[n] = (reg.D[n] & 0xffff0000) | data;
                   3642:                ACC.move_16(data);
                   3643:        } else if (n < 16) {
                   3644:                // CMPM.W (Ay)+,(Ax)+
1.1.1.2   root     3645:                CYCLE3(cmpm);
1.1       root     3646:                save_reg_pi_if(RegIRY);
                   3647:                save_reg_pi_if(RegIRX);
                   3648:                uint32 srcea = internal_ea_anpi_2(RegIRY);
                   3649:                uint32 dstea = internal_ea_anpi_2(RegIRX);
                   3650:                uint32 src = read_2(srcea);
                   3651:                uint32 dst = read_2(dstea);
                   3652:                ACC.cmp_16(src, dst);
                   3653:        } else {
                   3654:                // EOR.W Dx,<ea>
1.1.1.2   root     3655:                CYCLE3(eor_dn_ea);
1.1       root     3656:                uint32 ea = cea_data_2();
                   3657:                uint32 data = read_2(ea);
                   3658:                data ^= (RegDX & 0xffff);
                   3659:                ACC.move_16(data);
1.1.1.3 ! root     3660:                write_2(ea, data);
1.1       root     3661:        }
                   3662: }
                   3663: 
                   3664: // %1011_xxx110_mmmrrr d.m+-rxw.. 034  EOR.L Dx,<ea>
                   3665: // %1011_xxx110_001yyy .......... 034  CMPM.L (Ay)+,(Ax)+
                   3666: OP_DEF(eor_l)
                   3667: {
                   3668:        uint n = ir & 0x3f;
                   3669: 
                   3670:        if (n < 8) {
                   3671:                // EOR.L Dx,Dy
1.1.1.2   root     3672:                CYCLE3(eor_dn_dn);
1.1       root     3673:                reg.D[n] ^= RegDX;
                   3674:                ACC.move_32(reg.D[n]);
                   3675:        } else if (n < 16) {
                   3676:                // CMPM.L (Ay)+,(Ax)+
1.1.1.2   root     3677:                CYCLE3(cmpm);
1.1       root     3678:                save_reg_pi_if(RegIRY);
                   3679:                save_reg_pi_if(RegIRX);
                   3680:                uint32 srcea = internal_ea_anpi_4(RegIRY);
                   3681:                uint32 dstea = internal_ea_anpi_4(RegIRX);
                   3682:                uint32 src = read_4(srcea);
                   3683:                uint32 dst = read_4(dstea);
                   3684:                ACC.cmp_32(src, dst);
                   3685:        } else {
                   3686:                // EOR.L Dx,<ea>
1.1.1.2   root     3687:                CYCLE3(eor_dn_ea);
1.1       root     3688:                uint32 ea = cea_data_4();
                   3689:                uint32 data = read_4(ea);
                   3690:                data ^= RegDX;
                   3691:                ACC.move_32(data);
1.1.1.3 ! root     3692:                write_4(ea, data);
1.1       root     3693:        }
                   3694: }
                   3695: 
                   3696: // %1011_xxx111_mmmrrr dam+-rxwpi 034  CMPA.L <ea>,Ax
                   3697: OP_DEF(cmpa_l)
                   3698: {
1.1.1.2   root     3699:        CYCLE3(cmpa);
1.1       root     3700:        uint32 src = fea_all_4();
                   3701:        ACC.cmp_32(src, RegAX);
                   3702: }
                   3703: 
                   3704: // %1100_xxx000_mmmrrr d.m+-rxwpi 034  AND.B <ea>,Dx
                   3705: OP_DEF(and_b_ea_dn)
                   3706: {
1.1.1.2   root     3707:        CYCLE3(and_ea_dn);
1.1       root     3708:        uint32 src = fea_data_1();
                   3709:        uint32 dst = (RegDX & 0x000000ff) & src;
                   3710:        ACC.move_8(dst);
                   3711:        RegDX = (RegDX & 0xffffff00) | dst;
                   3712: }
                   3713: 
                   3714: // %1100_xxx001_mmmrrr d.m+-rxwpi 034  AND.W <ea>,Dx
                   3715: OP_DEF(and_w_ea_dn)
                   3716: {
1.1.1.2   root     3717:        CYCLE3(and_ea_dn);
1.1       root     3718:        uint32 src = fea_data_2();
                   3719:        uint32 dst = (RegDX & 0x0000ffff) & src;
                   3720:        ACC.move_16(dst);
                   3721:        RegDX = (RegDX & 0xffff0000) | dst;
                   3722: }
                   3723: 
                   3724: // %1100_xxx010_mmmrrr d.m+-rxwpi 034  AND.L <ea>,Dx
                   3725: OP_DEF(and_l_ea_dn)
                   3726: {
1.1.1.2   root     3727:        CYCLE3(and_ea_dn);
1.1       root     3728:        uint32 src = fea_data_4();
                   3729:        RegDX = RegDX & src;
                   3730:        ACC.move_32(RegDX);
                   3731: }
                   3732: 
                   3733: // %1100_xxx011_mmmrrr d.m+-rxwpi 034  MULU.W <ea>,Dx
                   3734: OP_DEF(mulu_w)
                   3735: {
1.1.1.2   root     3736:        CYCLE3(mulu_w_max);
1.1       root     3737:        uint32 src = fea_data_2();
                   3738:        uint32 dst = RegDX & 0xffff;
                   3739:        RegDX = ACC.mulu_16(src, dst);
                   3740: }
                   3741: 
                   3742: // %1100_xxx100_mmmrrr ..m+-rxw.. 034  AND.B Dx,<ea>
                   3743: // %1100_xxx100_000yyy .......... 034  ABCD.B Dy,Dx
                   3744: // %1100_xxx100_001yyy .......... 034  ABCD.B -(Ay),-(Ax)
                   3745: OP_DEF(and_b_dn_ea)
                   3746: {
                   3747:        uint n = ir & 0x3f;
                   3748: 
                   3749:        if (n < 8) {
                   3750:                // ABCD.B Dy,Dx
1.1.1.2   root     3751:                CYCLE3(abcd_dn);
1.1       root     3752:                uint32 src = RegDY & 0xff;
                   3753:                uint32 dst = RegDX & 0xff;
                   3754:                dst = ACC.abcd_8(src, dst);
                   3755:                RegDX &= 0xffffff00;
                   3756:                RegDX |= dst;
                   3757:                return;
                   3758:        } else if (n < 16) {
                   3759:                // ABCD.B -(Ay),-(Ax)
1.1.1.2   root     3760:                CYCLE3(abcd_an);
1.1       root     3761:                save_reg_pd_if(RegIRY);
                   3762:                save_reg_pd_if(RegIRX);
                   3763:                uint32 srcea = internal_ea_anpd_1(RegIRY);
                   3764:                uint32 dstea = internal_ea_anpd_1(RegIRX);
                   3765:                uint32 src = read_1(srcea);
                   3766:                uint32 dst = read_1(dstea);
                   3767:                dst = ACC.abcd_8(src, dst);
                   3768:                write_1(dstea, dst);
                   3769:                return;
                   3770:        } else {
                   3771:                // AND.B Dx,<ea>
1.1.1.2   root     3772:                CYCLE3(and_ea_dn);
1.1       root     3773:                uint32 ea = cea_data_1();
                   3774:                uint32 dst = read_1(ea);
                   3775:                dst &= RegDX & 0xff;
                   3776:                ACC.move_8(dst);
                   3777:                write_1(ea, dst);
                   3778:        }
                   3779: }
                   3780: 
                   3781: // %1100_xxx101_mmmrrr ..m+-rxw.. 034  AND.W Dx,<ea>
                   3782: // %1100_xxx101_000yyy .......... 034  EXG.L Dx,Dy
                   3783: // %1100_xxx101_001yyy .......... 034  EXG.L Ax,Ay
                   3784: OP_DEF(and_w_dn_ea)
                   3785: {
                   3786:        uint n = ir & 0x3f;
                   3787: 
                   3788:        if (n < 8) {
                   3789:                // EXG.L Dx,Dy
1.1.1.2   root     3790:                CYCLE3(exg);
1.1       root     3791:                uint x = RegIRX;
                   3792:                uint y = n;
                   3793:                uint32 tmp = reg.D[x];
                   3794:                reg.D[x] = reg.D[y];
                   3795:                reg.D[y] = tmp;
                   3796:                return;
                   3797:        } else if (n < 16) {
                   3798:                // EXG.L Ax,Ay
                   3799:                // ここでは x は 0..7 で A(x)、y は 8..15 で R(y)
1.1.1.2   root     3800:                CYCLE3(exg);
1.1       root     3801:                uint x = RegIRX;
                   3802:                uint y = n;
                   3803:                uint32 tmp = reg.A[x];
                   3804:                reg.A[x] = reg.R[y];
                   3805:                reg.R[y] = tmp;
                   3806:                return;
                   3807:        } else {
                   3808:                // AND.W Dx,<ea>
1.1.1.2   root     3809:                CYCLE3(and_dn_ea);
1.1       root     3810:                uint32 ea = cea_data_2();
                   3811:                uint32 dst = read_2(ea);
                   3812:                dst &= RegDX & 0xffff;
                   3813:                ACC.move_16(dst);
                   3814:                write_2(ea, dst);
                   3815:        }
                   3816: }
                   3817: 
                   3818: // %1100_xxx110_mmmrrr ..m+-rxw.. 034  AND.L Dx,<ea>
                   3819: // %1100_xxx110_001yyy .......... 034  EXG.L Dx,Ay
                   3820: OP_DEF(and_l_dn_ea)
                   3821: {
                   3822:        uint n = ir & 0x3f;
                   3823: 
                   3824:        if (n < 8) {
                   3825:                op_illegal();
                   3826:                return;
                   3827:        } else if (n < 16) {
                   3828:                // EXG.L Dx,Ay
                   3829:                // ここでは x は 0..7 で D(x)、y は 8..15 で R(y)
1.1.1.2   root     3830:                CYCLE3(exg);
1.1       root     3831:                uint x = RegIRX;
                   3832:                uint y = n;
                   3833:                uint32 tmp = reg.D[x];
                   3834:                reg.D[x] = reg.R[y];
                   3835:                reg.R[y] = tmp;
                   3836:                return;
                   3837:        } else {
                   3838:                // AND.L Dx,<ea>
1.1.1.2   root     3839:                CYCLE3(and_dn_ea);
1.1       root     3840:                uint32 ea = cea_data_4();
                   3841:                uint32 dst = read_4(ea);
                   3842:                dst &= RegDX;
                   3843:                ACC.move_32(dst);
                   3844:                write_4(ea, dst);
                   3845:        }
                   3846: }
                   3847: 
                   3848: // %1100_xxx111_mmmrrr d.m+-rxwpi 034  MULS.W <ea>,Dx
                   3849: OP_DEF(muls_w)
                   3850: {
1.1.1.2   root     3851:        CYCLE3(muls_w_max);
1.1       root     3852:        uint32 src = fea_data_2();
                   3853:        uint32 dst = RegDX & 0xffff;
                   3854:        RegDX = ACC.muls_16(src, dst);
                   3855: }
                   3856: 
                   3857: // %1101_xxx000_mmmrrr dam+-rxwpi 034  ADD.B <ea>,Dx
                   3858: OP_DEF(add_b_ea_dn)
                   3859: {
1.1.1.2   root     3860:        CYCLE3(add_ea_dn);
1.1       root     3861:        uint32 src = fea_all_1();
                   3862:        uint32 data = ACC.add_8(src, RegDX & 0xff);
                   3863:        RegDX = (RegDX & 0xffffff00) | data;
                   3864: }
                   3865: 
                   3866: // %1101_xxx001_mmmrrr dam+-rxwpi 034  ADD.W <ea>,Dx
                   3867: OP_DEF(add_w_ea_dn)
                   3868: {
1.1.1.2   root     3869:        CYCLE3(add_ea_dn);
1.1       root     3870:        uint32 src = fea_all_2();
                   3871:        uint32 data = ACC.add_16(src, RegDX & 0xffff);
                   3872:        RegDX = (RegDX & 0xffff0000) | data;
                   3873: }
                   3874: 
                   3875: // %1101_xxx010_mmmrrr dam+-rxwpi 034  ADD.L <ea>,Dx
                   3876: OP_DEF(add_l_ea_dn)
                   3877: {
1.1.1.2   root     3878:        CYCLE3(add_ea_dn);
1.1       root     3879:        uint32 src = fea_all_4();
                   3880:        RegDX = ACC.add_32(src, RegDX);
                   3881: }
                   3882: 
                   3883: // %1101_xxx011_mmmrrr dam+-rxwpi 034  ADDA.W <ea>,Ax
                   3884: OP_DEF(adda_w)
                   3885: {
1.1.1.2   root     3886:        CYCLE3(adda_w);
1.1       root     3887:        uint32 src = (int32)(int16)fea_all_2();
                   3888:        RegAX += src;
                   3889: }
                   3890: 
                   3891: // %1101_xxx100_mmmrrr ..m+-rxw.. 034  ADD.B Dx,<ea>
                   3892: // %1101_xxx100_000yyy .......... 034  ADDX.B Dy,Dx
                   3893: // %1101_xxx100_001yyy .......... 034  ADDX.B -(Ay),-(Ax)
                   3894: OP_DEF(add_b_dn_ea)
                   3895: {
                   3896:        uint n = ir & 0x3f;
                   3897: 
                   3898:        if (n < 8) {
                   3899:                // ADDX.B Dy,Dx
1.1.1.2   root     3900:                CYCLE3(addx_dn);
1.1       root     3901:                uint32 src = RegDY & 0xff;
                   3902:                uint32 dst = RegDX & 0xff;
                   3903:                dst = ACC.addx_8(src, dst);
                   3904:                RegDX = (RegDX & 0xffffff00) | dst;
                   3905:        } else if (n < 16) {
                   3906:                // ADDX.B -(Ay),-(Ax)
1.1.1.2   root     3907:                CYCLE3(addx_an);
1.1       root     3908:                save_reg_pd_if(RegIRY);
                   3909:                save_reg_pd_if(RegIRX);
                   3910:                uint32 srcea = internal_ea_anpd_1(RegIRY);
                   3911:                uint32 dstea = internal_ea_anpd_1(RegIRX);
                   3912:                uint32 src = read_1(srcea);
                   3913:                uint32 dst = read_1(dstea);
                   3914:                dst = ACC.addx_8(src, dst);
                   3915:                write_1(dstea, dst);
                   3916:        } else {
                   3917:                // ADD.B Dx,<ea>
1.1.1.2   root     3918:                CYCLE3(add_dn_ea);
1.1       root     3919:                uint32 ea = cea_data_1();
                   3920:                uint32 data = read_1(ea);
                   3921:                data = ACC.add_8(RegDX & 0xff, data);
                   3922:                write_1(ea, data);
                   3923:        }
                   3924: }
                   3925: 
                   3926: // %1101_xxx101_mmmrrr ..m+-rxw.. 034  ADD.W Dx,<ea>
                   3927: // %1101_xxx101_000yyy .......... 034  ADDX.W Dy,Dx
                   3928: // %1101_xxx101_001yyy .......... 034  ADDX.W -(Ay),-(Ax)
                   3929: OP_DEF(add_w_dn_ea)
                   3930: {
                   3931:        uint n = ir & 0x3f;
                   3932: 
                   3933:        if (n < 8) {
                   3934:                // ADDX.W Dy,Dx
1.1.1.2   root     3935:                CYCLE3(addx_dn);
1.1       root     3936:                uint32 src = RegDY & 0xffff;
                   3937:                uint32 dst = RegDX & 0xffff;
                   3938:                dst = ACC.addx_16(src, dst);
                   3939:                RegDX = (RegDX & 0xffff0000) | dst;
                   3940:        } else if (n < 16) {
                   3941:                // ADDX.W -(Ay),-(Ax)
1.1.1.2   root     3942:                CYCLE3(addx_an);
1.1       root     3943:                save_reg_pd_if(RegIRY);
                   3944:                save_reg_pd_if(RegIRX);
                   3945:                uint32 srcea = internal_ea_anpd_2(RegIRY);
                   3946:                uint32 dstea = internal_ea_anpd_2(RegIRX);
                   3947:                uint32 src = read_2(srcea);
                   3948:                uint32 dst = read_2(dstea);
                   3949:                dst = ACC.addx_16(src, dst);
                   3950:                write_2(dstea, dst);
                   3951:        } else {
                   3952:                // ADD.W Dx,<ea>
1.1.1.2   root     3953:                CYCLE3(add_dn_ea);
1.1       root     3954:                uint32 ea = cea_data_2();
                   3955:                uint32 data = read_2(ea);
                   3956:                data = ACC.add_16(RegDX & 0xffff, data);
                   3957:                write_2(ea, data);
                   3958:        }
                   3959: }
                   3960: 
                   3961: // %1101_xxx110_mmmrrr ..m+-rxw.. 034  ADD.L Dx,<ea>
                   3962: // %1101_xxx110_000yyy .......... 034  ADDX.L Dy,Dx
                   3963: // %1101_xxx110_001yyy .......... 034  ADDX.L -(Ay),-(Ax)
                   3964: OP_DEF(add_l_dn_ea)
                   3965: {
                   3966:        uint n = ir & 0x3f;
                   3967: 
                   3968:        if (n < 8) {
                   3969:                // ADDX.L Dy,Dx
1.1.1.2   root     3970:                CYCLE3(addx_dn);
1.1       root     3971:                uint32 src = RegDY;
                   3972:                uint32 dst = RegDX;
                   3973:                RegDX = ACC.addx_32(src, dst);
                   3974:        } else if (n < 16) {
                   3975:                // ADDX.L -(Ay),-(Ax)
1.1.1.2   root     3976:                CYCLE3(addx_an);
1.1       root     3977:                save_reg_pd_if(RegIRY);
                   3978:                save_reg_pd_if(RegIRX);
                   3979:                uint32 srcea = internal_ea_anpd_4(RegIRY);
                   3980:                uint32 dstea = internal_ea_anpd_4(RegIRX);
                   3981:                uint32 src = read_4(srcea);
                   3982:                uint32 dst = read_4(dstea);
                   3983:                dst = ACC.addx_32(src, dst);
                   3984:                write_4(dstea, dst);
                   3985:        } else {
                   3986:                // ADD.L Dx,<ea>
1.1.1.2   root     3987:                CYCLE3(add_dn_ea);
1.1       root     3988:                uint32 ea = cea_data_4();
                   3989:                uint32 data = read_4(ea);
                   3990:                data = ACC.add_32(RegDX, data);
                   3991:                write_4(ea, data);
                   3992:        }
                   3993: }
                   3994: 
                   3995: // %1101_xxx111_mmmrrr dam+-rxwpi 034  ADDA.L <ea>,Ax
                   3996: OP_DEF(adda_l)
                   3997: {
1.1.1.2   root     3998:        CYCLE3(adda_l);
1.1       root     3999:        uint32 src = fea_all_4();
                   4000:        RegAX += src;
                   4001: }
                   4002: 
                   4003: // %1110_qqq000_000yyy .......... 034  ASR.B #qqq,Dy
                   4004: // %1110_qqq000_001yyy .......... 034  LSR.B #qqq,Dy
                   4005: // %1110_qqq000_010yyy .......... 034  ROXR.B #qqq,Dy
                   4006: // %1110_qqq000_011yyy .......... 034  ROR.B #qqq,Dy
                   4007: // %1110_xxx000_100yyy .......... 034  ASR.B Dx,Dy
                   4008: // %1110_xxx000_101yyy .......... 034  LSR.B Dx,Dy
                   4009: // %1110_xxx000_110yyy .......... 034  ROXR.B Dx,Dy
                   4010: // %1110_xxx000_111yyy .......... 034  ROR.B Dx,Dy
                   4011: OP_DEF(asr_b_imm)
                   4012: {
                   4013:        int count;
                   4014:        uint32 data;
                   4015:        switch (eamode(ir)) {
                   4016:         case 0:        // ASR.B #qqq,Dy
1.1.1.2   root     4017:                CYCLE3(asr_imm_dn);
1.1       root     4018:                count = RegIRX;
                   4019:                count = (count == 0) ? 8 : count;
                   4020:                __assume(1 <= count && count <= 8);
                   4021:                data = ACC.asr_8(RegDY & 0xff, count);
                   4022:                RegDY = (RegDY & 0xffffff00) | data;
                   4023:                return;
                   4024:         case 1:        // LSR.B #qqq,Dy
1.1.1.2   root     4025:                CYCLE3(lsd_imm_dn);
1.1       root     4026:                count = RegIRX;
                   4027:                count = (count == 0) ? 8 : count;
                   4028:                __assume(1 <= count && count <= 8);
                   4029:                data = ACC.lsr_8(RegDY & 0xff, count);
                   4030:                RegDY = (RegDY & 0xffffff00) | data;
                   4031:                return;
                   4032:         case 2:        // ROXR.B #qqq,Dy
1.1.1.2   root     4033:                CYCLE3(roxd_dn);
1.1       root     4034:                count = RegIRX;
                   4035:                count = (count == 0) ? 8 : count;
                   4036:                __assume(1 <= count && count <= 8);
                   4037:                data = ACC.roxr_8(RegDY & 0xff, count);
                   4038:                RegDY = (RegDY & 0xffffff00) | data;
                   4039:                return;
                   4040:         case 3:        // ROR.B #qqq,Dy
1.1.1.2   root     4041:                CYCLE3(rod_imm_dn);
1.1       root     4042:                count = RegIRX;
                   4043:                count = (count == 0) ? 8 : count;
                   4044:                __assume(1 <= count && count <= 8);
                   4045:                data = ACC.ror_8(RegDY & 0xff, count);
                   4046:                RegDY = (RegDY & 0xffffff00) | data;
                   4047:                return;
                   4048:         case 4:        // ASR.B Dx,Dy
                   4049:                count = RegDX & 63;
                   4050:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4051:                if (count <= 8) {
                   4052:                        CYCLE3(asr_dn_dn_less);
                   4053:                } else {
                   4054:                        CYCLE3(asr_dn_dn_over);
                   4055:                }
1.1       root     4056:                __assume(0 <= count && count < 64);
                   4057:                data = ACC.asr_8(RegDY & 0xff, count);
                   4058:                RegDY = (RegDY & 0xffffff00) | data;
                   4059:                return;
                   4060:         case 5:        // LSR.B Dx,Dy
                   4061:                count = RegDX & 63;
                   4062:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4063:                if (count <= 8) {
                   4064:                        CYCLE3(lsd_dn_dn_less);
                   4065:                } else {
                   4066:                        CYCLE3(lsd_dn_dn_over);
                   4067:                }
1.1       root     4068:                __assume(0 <= count && count < 64);
                   4069:                data = ACC.lsr_8(RegDY & 0xff, count);
                   4070:                RegDY = (RegDY & 0xffffff00) | data;
                   4071:                return;
                   4072:         case 6:        // ROXR.B Dx,Dy
1.1.1.2   root     4073:                CYCLE3(roxd_dn);
1.1       root     4074:                count = RegDX & 63;
                   4075:                __assume(0 <= count && count < 64);
                   4076:                data = ACC.roxr_8(RegDY & 0xff, count);
                   4077:                RegDY = (RegDY & 0xffffff00) | data;
                   4078:                return;
                   4079:         case 7:        // ROR.B Dx,Dy
1.1.1.2   root     4080:                CYCLE3(rod_dn_dn);
1.1       root     4081:                count = RegDX & 63;
                   4082:                __assume(0 <= count && count < 64);
                   4083:                data = ACC.ror_8(RegDY & 0xff, count);
                   4084:                RegDY = (RegDY & 0xffffff00) | data;
                   4085:                return;
                   4086:        }
                   4087: }
                   4088: 
                   4089: // %1110_qqq001_000yyy .......... 034  ASR.W #qqq,Dy
                   4090: // %1110_qqq001_001yyy .......... 034  LSR.W #qqq,Dy
                   4091: // %1110_qqq001_010yyy .......... 034  ROXR.W #qqq,Dy
                   4092: // %1110_qqq001_011yyy .......... 034  ROR.W #qqq,Dy
                   4093: // %1110_xxx001_100yyy .......... 034  ASR.W Dx,Dy
                   4094: // %1110_xxx001_101yyy .......... 034  LSR.W Dx,Dy
                   4095: // %1110_xxx001_110yyy .......... 034  ROXR.W Dx,Dy
                   4096: // %1110_xxx001_111yyy .......... 034  ROR.W Dx,Dy
                   4097: OP_DEF(asr_w_imm)
                   4098: {
                   4099:        int count;
                   4100:        uint32 data;
                   4101:        switch (eamode(ir)) {
                   4102:         case 0:        // ASR.W #qqq,Dy
1.1.1.2   root     4103:                CYCLE3(asr_imm_dn);
1.1       root     4104:                count = RegIRX;
                   4105:                count = (count == 0) ? 8 : count;
                   4106:                __assume(1 <= count && count <= 8);
                   4107:                data = ACC.asr_16(RegDY & 0xffff, count);
                   4108:                RegDY = (RegDY & 0xffff0000) | data;
                   4109:                return;
                   4110:         case 1:        // LSR.W #qqq,Dy
1.1.1.2   root     4111:                CYCLE3(lsd_imm_dn);
1.1       root     4112:                count = RegIRX;
                   4113:                count = (count == 0) ? 8 : count;
                   4114:                __assume(1 <= count && count <= 8);
                   4115:                data = ACC.lsr_16(RegDY & 0xffff, count);
                   4116:                RegDY = (RegDY & 0xffff0000) | data;
                   4117:                return;
                   4118:         case 2:        // ROXR.W #qqq,Dy
1.1.1.2   root     4119:                CYCLE3(roxd_dn);
1.1       root     4120:                count = RegIRX;
                   4121:                count = (count == 0) ? 8 : count;
                   4122:                __assume(1 <= count && count <= 8);
                   4123:                data = ACC.roxr_16(RegDY & 0xffff, count);
                   4124:                RegDY = (RegDY & 0xffff0000) | data;
                   4125:                return;
                   4126:         case 3:        // ROR.W #qqq,Dy
1.1.1.2   root     4127:                CYCLE3(rod_imm_dn);
1.1       root     4128:                count = RegIRX;
                   4129:                count = (count == 0) ? 8 : count;
                   4130:                __assume(1 <= count && count <= 8);
                   4131:                data = ACC.ror_16(RegDY & 0xffff, count);
                   4132:                RegDY = (RegDY & 0xffff0000) | data;
                   4133:                return;
                   4134:         case 4:        // ASR.W Dx,Dy
                   4135:                count = RegDX & 63;
                   4136:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4137:                if (count <= 16) {
                   4138:                        CYCLE3(asr_dn_dn_less);
                   4139:                } else {
                   4140:                        CYCLE3(asr_dn_dn_over);
                   4141:                }
1.1       root     4142:                __assume(0 <= count && count < 64);
                   4143:                data = ACC.asr_16(RegDY & 0xffff, count);
                   4144:                RegDY = (RegDY & 0xffff0000) | data;
                   4145:                return;
                   4146:         case 5:        // LSR.W Dx,Dy
                   4147:                count = RegDX & 63;
                   4148:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4149:                if (count <= 16) {
                   4150:                        CYCLE3(lsd_dn_dn_less);
                   4151:                } else {
                   4152:                        CYCLE3(lsd_dn_dn_over);
                   4153:                }
1.1       root     4154:                __assume(0 <= count && count < 64);
                   4155:                data = ACC.lsr_16(RegDY & 0xffff, count);
                   4156:                RegDY = (RegDY & 0xffff0000) | data;
                   4157:                return;
                   4158:         case 6:        // ROXR.W Dx,Dy
1.1.1.2   root     4159:                CYCLE3(roxd_dn);
1.1       root     4160:                count = RegDX & 63;
                   4161:                __assume(0 <= count && count < 64);
                   4162:                data = ACC.roxr_16(RegDY & 0xffff, count);
                   4163:                RegDY = (RegDY & 0xffff0000) | data;
                   4164:                return;
                   4165:         case 7:        // ROR.W Dx,Dy
1.1.1.2   root     4166:                CYCLE3(rod_dn_dn);
1.1       root     4167:                count = RegDX & 63;
                   4168:                __assume(0 <= count && count < 64);
                   4169:                data = ACC.ror_16(RegDY & 0xffff, count);
                   4170:                RegDY = (RegDY & 0xffff0000) | data;
                   4171:                return;
                   4172:        }
                   4173: }
                   4174: 
                   4175: // %1110_qqq010_000yyy .......... 034  ASR.L #qqq,Dy
                   4176: // %1110_qqq010_001yyy .......... 034  LSR.L #qqq,Dy
                   4177: // %1110_qqq010_010yyy .......... 034  ROXR.L #qqq,Dy
                   4178: // %1110_qqq010_011yyy .......... 034  ROR.L #qqq,Dy
                   4179: // %1110_xxx010_100yyy .......... 034  ASR.L Dx,Dy
                   4180: // %1110_xxx010_101yyy .......... 034  LSR.L Dx,Dy
                   4181: // %1110_xxx010_110yyy .......... 034  ROXR.L Dx,Dy
                   4182: // %1110_xxx010_111yyy .......... 034  ROR.L Dx,Dy
                   4183: OP_DEF(asr_l_imm)
                   4184: {
                   4185:        int count;
                   4186:        switch (eamode(ir)) {
                   4187:         case 0:        // ASR.L #qqq,Dy
1.1.1.2   root     4188:                CYCLE3(asr_imm_dn);
1.1       root     4189:                count = RegIRX;
                   4190:                count = (count == 0) ? 8 : count;
                   4191:                __assume(1 <= count && count <= 8);
                   4192:                RegDY = ACC.asr_32(RegDY, count);
                   4193:                return;
                   4194:         case 1:        // LSR.L #qqq,Dy
1.1.1.2   root     4195:                CYCLE3(lsd_imm_dn);
1.1       root     4196:                count = RegIRX;
                   4197:                count = (count == 0) ? 8 : count;
                   4198:                __assume(1 <= count && count <= 8);
                   4199:                RegDY = ACC.lsr_32(RegDY, count);
                   4200:                return;
                   4201:         case 2:        // ROXR.L #qqq,Dy
1.1.1.2   root     4202:                CYCLE3(roxd_dn);
1.1       root     4203:                count = RegIRX;
                   4204:                count = (count == 0) ? 8 : count;
                   4205:                __assume(1 <= count && count <= 8);
                   4206:                RegDY = ACC.roxr_32(RegDY, count);
                   4207:                return;
                   4208:         case 3:        // ROR.L #qqq,Dy
1.1.1.2   root     4209:                CYCLE3(rod_imm_dn);
1.1       root     4210:                count = RegIRX;
                   4211:                count = (count == 0) ? 8 : count;
                   4212:                __assume(1 <= count && count <= 8);
                   4213:                RegDY = ACC.ror_32(RegDY, count);
                   4214:                return;
                   4215:         case 4:        // ASR.L Dx,Dy
                   4216:                count = RegDX & 63;
                   4217:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4218:                if (count <= 32) {
                   4219:                        CYCLE3(asr_dn_dn_less);
                   4220:                } else {
                   4221:                        CYCLE3(asr_dn_dn_over);
                   4222:                }
1.1       root     4223:                __assume(0 <= count && count < 64);
                   4224:                RegDY = ACC.asr_32(RegDY, count);
                   4225:                return;
                   4226:         case 5:        // LSR.L Dx,Dy
                   4227:                count = RegDX & 63;
                   4228:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4229:                if (count <= 32) {
                   4230:                        CYCLE3(lsd_dn_dn_less);
                   4231:                } else {
                   4232:                        CYCLE3(lsd_dn_dn_over);
                   4233:                }
1.1       root     4234:                __assume(0 <= count && count < 64);
                   4235:                RegDY = ACC.lsr_32(RegDY, count);
                   4236:                return;
                   4237:         case 6:        // ROXR.L Dx,Dy
1.1.1.2   root     4238:                CYCLE3(roxd_dn);
1.1       root     4239:                count = RegDX & 63;
                   4240:                __assume(0 <= count && count < 64);
                   4241:                RegDY = ACC.roxr_32(RegDY, count);
                   4242:                return;
                   4243:         case 7:        // ROR.L Dx,Dy
1.1.1.2   root     4244:                CYCLE3(rod_dn_dn);
1.1       root     4245:                count = RegDX & 63;
                   4246:                __assume(0 <= count && count < 64);
                   4247:                RegDY = ACC.ror_32(RegDY, count);
                   4248:                return;
                   4249:        }
                   4250: }
                   4251: 
                   4252: // %1110_000011_mmmrrr ..m+-rxw.. 034  ASR.W <ea>
                   4253: OP_DEF(asr_w)
                   4254: {
1.1.1.2   root     4255:        CYCLE3(asr_w);
1.1       root     4256:        uint32 ea = cea_data_2();
                   4257:        uint32 data = read_2(ea);
                   4258:        data = ACC.asr_16(data, 1);
                   4259:        write_2(ea, data);
                   4260: }
                   4261: 
                   4262: // %1110_qqq100_000yyy .......... 034  ASL.B #qqq,Dy
                   4263: // %1110_qqq100_001yyy .......... 034  LSL.B #qqq,Dy
                   4264: // %1110_qqq100_010yyy .......... 034  ROXL.B #qqq,Dy
                   4265: // %1110_qqq100_011yyy .......... 034  ROL.B #qqq,Dy
                   4266: // %1110_xxx100_100yyy .......... 034  ASL.B Dx,Dy
                   4267: // %1110_xxx100_101yyy .......... 034  LSL.B Dx,Dy
                   4268: // %1110_xxx100_110yyy .......... 034  ROXL.B Dx,Dy
                   4269: // %1110_xxx100_111yyy .......... 034  ROL.B Dx,Dy
                   4270: OP_DEF(asl_b_imm)
                   4271: {
                   4272:        int count;
                   4273:        uint32 data;
                   4274:        switch (eamode(ir)) {
                   4275:         case 0:        // ASL.B #qqq,Dy
1.1.1.2   root     4276:                CYCLE3(asl_imm_dn);
1.1       root     4277:                count = RegIRX;
                   4278:                count = (count == 0) ? 8 : count;
                   4279:                __assume(1 <= count && count <= 8);
                   4280:                data = ACC.asl_8(RegDY & 0xff, count);
                   4281:                RegDY = (RegDY & 0xffffff00) | data;
                   4282:                return;
                   4283:         case 1:        // LSL.B #qqq,Dy
1.1.1.2   root     4284:                CYCLE3(lsd_imm_dn);
1.1       root     4285:                count = RegIRX;
                   4286:                count = (count == 0) ? 8 : count;
                   4287:                __assume(1 <= count && count <= 8);
                   4288:                data = ACC.lsl_8(RegDY & 0xff, count);
                   4289:                RegDY = (RegDY & 0xffffff00) | data;
                   4290:                return;
                   4291:         case 2:        // ROXL.B #qqq,Dy
1.1.1.2   root     4292:                CYCLE3(roxd_dn);
1.1       root     4293:                count = RegIRX;
                   4294:                count = (count == 0) ? 8 : count;
                   4295:                __assume(1 <= count && count <= 8);
                   4296:                data = ACC.roxl_8(RegDY & 0xff, count);
                   4297:                RegDY = (RegDY & 0xffffff00) | data;
                   4298:                return;
                   4299:         case 3:        // ROL.B #qqq,Dy
1.1.1.2   root     4300:                CYCLE3(rod_imm_dn);
1.1       root     4301:                count = RegIRX;
                   4302:                count = (count == 0) ? 8 : count;
                   4303:                __assume(1 <= count && count <= 8);
                   4304:                data = ACC.rol_8(RegDY & 0xff, count);
                   4305:                RegDY = (RegDY & 0xffffff00) | data;
                   4306:                return;
                   4307:         case 4:        // ASL.B Dx,Dy
1.1.1.2   root     4308:                CYCLE3(asl_dn_dn);
1.1       root     4309:                count = RegDX & 63;
                   4310:                __assume(0 <= count && count < 64);
                   4311:                data = ACC.asl_8(RegDY & 0xff, count);
                   4312:                RegDY = (RegDY & 0xffffff00) | data;
                   4313:                return;
                   4314:         case 5:        // LSL.B Dx,Dy
                   4315:                count = RegDX & 63;
                   4316:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4317:                if (count <= 8) {
                   4318:                        CYCLE3(lsd_dn_dn_less);
                   4319:                } else {
                   4320:                        CYCLE3(lsd_dn_dn_over);
                   4321:                }
1.1       root     4322:                __assume(0 <= count && count < 64);
                   4323:                data = ACC.lsl_8(RegDY & 0xff, count);
                   4324:                RegDY = (RegDY & 0xffffff00) | data;
                   4325:                return;
                   4326:         case 6:        // ROXL.B Dx,Dy
1.1.1.2   root     4327:                CYCLE3(roxd_dn);
1.1       root     4328:                count = RegDX & 63;
                   4329:                __assume(0 <= count && count < 64);
                   4330:                data = ACC.roxl_8(RegDY & 0xff, count);
                   4331:                RegDY = (RegDY & 0xffffff00) | data;
                   4332:                return;
                   4333:         case 7:        // ROL.B Dx,Dy
1.1.1.2   root     4334:                CYCLE3(rod_dn_dn);
1.1       root     4335:                count = RegDX & 63;
                   4336:                __assume(0 <= count && count < 64);
                   4337:                data = ACC.rol_8(RegDY & 0xff, count);
                   4338:                RegDY = (RegDY & 0xffffff00) | data;
                   4339:                return;
                   4340:        }
                   4341: }
                   4342: 
                   4343: // %1110_qqq101_000yyy .......... 034  ASL.W #qqq,Dy
                   4344: // %1110_qqq101_001yyy .......... 034  LSL.W #qqq,Dy
                   4345: // %1110_qqq101_010yyy .......... 034  ROXL.W #qqq,Dy
                   4346: // %1110_qqq101_011yyy .......... 034  ROL.W #qqq,Dy
                   4347: // %1110_xxx101_100yyy .......... 034  ASL.W Dx,Dy
                   4348: // %1110_xxx101_101yyy .......... 034  LSL.W Dx,Dy
                   4349: // %1110_xxx101_110yyy .......... 034  ROXL.W Dx,Dy
                   4350: // %1110_xxx101_111yyy .......... 034  ROL.W Dx,Dy
                   4351: OP_DEF(asl_w_imm)
                   4352: {
                   4353:        int count;
                   4354:        uint32 data;
                   4355:        switch (eamode(ir)) {
                   4356:         case 0:        // ASL.W #qqq,Dy
1.1.1.2   root     4357:                CYCLE3(asl_imm_dn);
1.1       root     4358:                count = RegIRX;
                   4359:                count = (count == 0) ? 8 : count;
                   4360:                __assume(1 <= count && count <= 8);
                   4361:                data = ACC.asl_16(RegDY & 0xffff, count);
                   4362:                RegDY = (RegDY & 0xffff0000) | data;
                   4363:                return;
                   4364:         case 1:        // LSL.W #qqq,Dy
1.1.1.2   root     4365:                CYCLE3(lsd_imm_dn);
1.1       root     4366:                count = RegIRX;
                   4367:                count = (count == 0) ? 8 : count;
                   4368:                __assume(1 <= count && count <= 8);
                   4369:                data = ACC.lsl_16(RegDY & 0xffff, count);
                   4370:                RegDY = (RegDY & 0xffff0000) | data;
                   4371:                return;
                   4372:         case 2:        // ROXL.W #qqq,Dy
1.1.1.2   root     4373:                CYCLE3(roxd_dn);
1.1       root     4374:                count = RegIRX;
                   4375:                count = (count == 0) ? 8 : count;
                   4376:                __assume(1 <= count && count <= 8);
                   4377:                data = ACC.roxl_16(RegDY & 0xffff, count);
                   4378:                RegDY = (RegDY & 0xffff0000) | data;
                   4379:                return;
                   4380:         case 3:        // ROL.W #qqq,Dy
1.1.1.2   root     4381:                CYCLE3(rod_imm_dn);
1.1       root     4382:                count = RegIRX;
                   4383:                count = (count == 0) ? 8 : count;
                   4384:                __assume(1 <= count && count <= 8);
                   4385:                data = ACC.rol_16(RegDY & 0xffff, count);
                   4386:                RegDY = (RegDY & 0xffff0000) | data;
                   4387:                return;
                   4388:         case 4:        // ASL.W Dx,Dy
1.1.1.2   root     4389:                CYCLE3(asl_dn_dn);
1.1       root     4390:                count = RegDX & 63;
                   4391:                __assume(0 <= count && count < 64);
                   4392:                data = ACC.asl_16(RegDY & 0xffff, count);
                   4393:                RegDY = (RegDY & 0xffff0000) | data;
                   4394:                return;
                   4395:         case 5:        // LSL.W Dx,Dy
                   4396:                count = RegDX & 63;
                   4397:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4398:                if (count <= 16) {
                   4399:                        CYCLE3(lsd_dn_dn_less);
                   4400:                } else {
                   4401:                        CYCLE3(lsd_dn_dn_over);
                   4402:                }
1.1       root     4403:                __assume(0 <= count && count < 64);
                   4404:                data = ACC.lsl_16(RegDY & 0xffff, count);
                   4405:                RegDY = (RegDY & 0xffff0000) | data;
                   4406:                return;
                   4407:         case 6:        // ROXL.W Dx,Dy
1.1.1.2   root     4408:                CYCLE3(roxd_dn);
1.1       root     4409:                count = RegDX & 63;
                   4410:                __assume(0 <= count && count < 64);
                   4411:                data = ACC.roxl_16(RegDY & 0xffff, count);
                   4412:                RegDY = (RegDY & 0xffff0000) | data;
                   4413:                return;
                   4414:         case 7:        // ROL.W Dx,Dy
1.1.1.2   root     4415:                CYCLE3(rod_dn_dn);
1.1       root     4416:                count = RegDX & 63;
                   4417:                __assume(0 <= count && count < 64);
                   4418:                data = ACC.rol_16(RegDY & 0xffff, count);
                   4419:                RegDY = (RegDY & 0xffff0000) | data;
                   4420:                return;
                   4421:        }
                   4422: }
                   4423: 
                   4424: // %1110_qqq110_000yyy .......... 034  ASL.L #qqq,Dy
                   4425: // %1110_qqq110_001yyy .......... 034  LSL.L #qqq,Dy
                   4426: // %1110_qqq110_010yyy .......... 034  ROXL.L #qqq,Dy
                   4427: // %1110_qqq110_011yyy .......... 034  ROL.L #qqq,Dy
                   4428: // %1110_xxx110_100yyy .......... 034  ASL.L Dx,Dy
                   4429: // %1110_xxx110_101yyy .......... 034  LSL.L Dx,Dy
                   4430: // %1110_xxx110_110yyy .......... 034  ROXL.L Dx,Dy
                   4431: // %1110_xxx110_111yyy .......... 034  ROL.L Dx,Dy
                   4432: OP_DEF(asl_l_imm)
                   4433: {
                   4434:        int count;
                   4435:        switch (eamode(ir)) {
                   4436:         case 0:        // ASL.L #qqq,Dy
1.1.1.2   root     4437:                CYCLE3(asl_imm_dn);
1.1       root     4438:                count = RegIRX;
                   4439:                count = (count == 0) ? 8 : count;
                   4440:                __assume(1 <= count && count <= 8);
                   4441:                RegDY = ACC.asl_32(RegDY, count);
                   4442:                return;
                   4443:         case 1:        // LSL.L #qqq,Dy
1.1.1.2   root     4444:                CYCLE3(lsd_imm_dn);
1.1       root     4445:                count = RegIRX;
                   4446:                count = (count == 0) ? 8 : count;
                   4447:                __assume(1 <= count && count <= 8);
                   4448:                RegDY = ACC.lsl_32(RegDY, count);
                   4449:                return;
                   4450:         case 2:        // ROXL.L #qqq,Dy
1.1.1.2   root     4451:                CYCLE3(roxd_dn);
1.1       root     4452:                count = RegIRX;
                   4453:                count = (count == 0) ? 8 : count;
                   4454:                __assume(1 <= count && count <= 8);
                   4455:                RegDY = ACC.roxl_32(RegDY, count);
                   4456:                return;
                   4457:         case 3:        // ROL.L #qqq,Dy
1.1.1.2   root     4458:                CYCLE3(rod_imm_dn);
1.1       root     4459:                count = RegIRX;
                   4460:                count = (count == 0) ? 8 : count;
                   4461:                __assume(1 <= count && count <= 8);
                   4462:                RegDY = ACC.rol_32(RegDY, count);
                   4463:                return;
                   4464:         case 4:        // ASL.L Dx,Dy
1.1.1.2   root     4465:                CYCLE3(asl_dn_dn);
1.1       root     4466:                count = RegDX & 63;
                   4467:                __assume(0 <= count && count < 64);
                   4468:                RegDY = ACC.asl_32(RegDY, count);
                   4469:                return;
                   4470:         case 5:        // LSL.L Dx,Dy
                   4471:                count = RegDX & 63;
                   4472:                // シフト数がデータサイズを越えるかどうかでサイクルが違う
1.1.1.2   root     4473:                if (count <= 32) {
                   4474:                        CYCLE3(lsd_dn_dn_less);
                   4475:                } else {
                   4476:                        CYCLE3(lsd_dn_dn_over);
                   4477:                }
1.1       root     4478:                __assume(0 <= count && count < 64);
                   4479:                RegDY = ACC.lsl_32(RegDY, count);
                   4480:                return;
                   4481:         case 6:        // ROXL.L Dx,Dy
1.1.1.2   root     4482:                CYCLE3(roxd_dn);
1.1       root     4483:                count = RegDX & 63;
                   4484:                __assume(0 <= count && count < 64);
                   4485:                RegDY = ACC.roxl_32(RegDY, count);
                   4486:                return;
                   4487:         case 7:        // ROL.L Dx,Dy
1.1.1.2   root     4488:                CYCLE3(rod_dn_dn);
1.1       root     4489:                count = RegDX & 63;
                   4490:                __assume(0 <= count && count < 64);
                   4491:                RegDY = ACC.rol_32(RegDY, count);
                   4492:                return;
                   4493:        }
                   4494: }
                   4495: 
                   4496: // %1110_000111_mmmrrr ..m+-rxw.. 034  ASL.W <ea>
                   4497: OP_DEF(asl_w)
                   4498: {
1.1.1.2   root     4499:        CYCLE3(asl_w);
1.1       root     4500:        uint32 ea = cea_data_2();
                   4501:        uint32 data = read_2(ea);
                   4502:        data = ACC.asl_16(data, 1);
                   4503:        write_2(ea, data);
                   4504: }
                   4505: 
                   4506: // %1110_001011_mmmrrr ..m+-rxw.. 034  LSR.W <ea>
                   4507: OP_DEF(lsr_w)
                   4508: {
1.1.1.2   root     4509:        CYCLE3(lsd_w);
1.1       root     4510:        uint32 ea = cea_data_2();
                   4511:        uint32 data = read_2(ea);
                   4512:        data = ACC.lsr_16(data, 1);
                   4513:        write_2(ea, data);
                   4514: }
                   4515: 
                   4516: // %1110_001111_mmmrrr ..m+-rxw.. 034  LSL.W <ea>
                   4517: OP_DEF(lsl_w)
                   4518: {
1.1.1.2   root     4519:        CYCLE3(lsd_w);
1.1       root     4520:        uint32 ea = cea_data_2();
                   4521:        uint32 data = read_2(ea);
                   4522:        data = ACC.lsl_16(data, 1);
                   4523:        write_2(ea, data);
                   4524: }
                   4525: 
                   4526: // %1110_010011_mmmrrr ..m+-rxw.. 034  ROXR.W <ea>
                   4527: OP_DEF(roxr_w)
                   4528: {
1.1.1.2   root     4529:        CYCLE3(roxd_w);
1.1       root     4530:        uint32 ea = cea_data_2();
                   4531:        uint32 data = read_2(ea);
                   4532:        data = ACC.roxr_16(data, 1);
                   4533:        write_2(ea, data);
                   4534: }
                   4535: 
                   4536: // %1110_010111_mmmrrr ..m+-rxw.. 034  ROXL.W <ea>
                   4537: OP_DEF(roxl_w)
                   4538: {
1.1.1.2   root     4539:        CYCLE3(roxd_w);
1.1       root     4540:        uint32 ea = cea_data_2();
                   4541:        uint32 data = read_2(ea);
                   4542:        data = ACC.roxl_16(data, 1);
                   4543:        write_2(ea, data);
                   4544: }
                   4545: 
                   4546: // %1110_011011_mmmrrr ..m+-rxw.. 034  ROR.W <ea>
                   4547: OP_DEF(ror_w)
                   4548: {
1.1.1.2   root     4549:        CYCLE3(rod_w);
1.1       root     4550:        uint32 ea = cea_data_2();
                   4551:        uint32 data = read_2(ea);
                   4552:        data = ACC.ror_16(data, 1);
                   4553:        write_2(ea, data);
                   4554: }
                   4555: 
                   4556: // %1110_011111_mmmrrr ..m+-rxw.. 034  ROL.W <ea>
                   4557: OP_DEF(rol_w)
                   4558: {
1.1.1.2   root     4559:        CYCLE3(rod_w);
1.1       root     4560:        uint32 ea = cea_data_2();
                   4561:        uint32 data = read_2(ea);
                   4562:        data = ACC.rol_16(data, 1);
                   4563:        write_2(ea, data);
                   4564: }
                   4565: 
                   4566: // %1110_100011_mmmrrr d.m..rxwp. -34  BFTST <ea>{#o:#w}
                   4567: OP_DEF(bftst)
                   4568: {
                   4569:        uint n = ir & 0x3f;
                   4570:        ir2 = fetch_2();
                   4571: 
                   4572:        acc_bf bf(this);
                   4573:        if (n < 8) {
                   4574:                // BFTST Dn{#o:#w}
1.1.1.2   root     4575:                CYCLE3(bftst_dn);
1.1       root     4576:                bf.LoadReg(n);
                   4577:        } else {
                   4578:                // BFTST <ea>{#o:#w}
                   4579:                uint32 ea = cea_ctrl();
1.1.1.2   root     4580:                if (__predict_true(bf.LoadMem(ea))) {
                   4581:                        CYCLE3(bftst_ea_less);
                   4582:                } else {
                   4583:                        CYCLE3(bftst_ea_over);
                   4584:                }
1.1       root     4585:        }
                   4586:        ACC.move_32(bf.data);
                   4587: }
                   4588: 
                   4589: // %1110_100111_mmmrrr d.m..rxwp. -34  BFEXTU <ea>{#o:#w},Dn
                   4590: OP_DEF(bfextu)
                   4591: {
                   4592:        uint n = ir & 0x3f;
                   4593:        ir2 = fetch_2();
                   4594:        uint dn = ir2 >> 12;
                   4595: 
                   4596:        acc_bf bf(this);
                   4597:        if (n < 8) {
                   4598:                // BFEXTU Dn{#o:#w},Dn
1.1.1.2   root     4599:                CYCLE3(bfext_dn);
1.1       root     4600:                bf.LoadReg(n);
                   4601:        } else {
                   4602:                // BFEXTU <ea>{#o:#w},Dn
                   4603:                uint32 ea = cea_ctrl();
1.1.1.2   root     4604:                if (__predict_true(bf.LoadMem(ea))) {
                   4605:                        CYCLE3(bfext_ea_less);
                   4606:                } else {
                   4607:                        CYCLE3(bfext_ea_over);
                   4608:                }
1.1       root     4609:        }
                   4610:        // CCR は操作前のビットフィールドに対して
                   4611:        ACC.move_32(bf.data);
                   4612:        // 符号なしシフト
                   4613:        reg.D[dn] = bf.data >> (32 - bf.width);
                   4614: }
                   4615: 
                   4616: // %1110_101011_mmmrrr d.m..rxw.. -34  BFCHG <ea>{#o:#w}
                   4617: OP_DEF(bfchg)
                   4618: {
                   4619:        uint n = ir & 0x3f;
                   4620:        ir2 = fetch_2();
                   4621: 
                   4622:        acc_bf bf(this);
                   4623:        if (n < 8) {
                   4624:                // BFCHG Dn{#o:#w}
1.1.1.2   root     4625:                CYCLE3(bfchg_dn);
1.1       root     4626:                bf.LoadReg(n);
                   4627:        } else if (n >= 0x3a) {
                   4628:                // BFCHG <ea> に PC 相対(と #imm) はない
                   4629:                op_illegal();
                   4630:        } else {
                   4631:                // BFCHG <ea>{#o:#w}
                   4632:                uint32 ea = cea_ctrl();
1.1.1.2   root     4633:                if (__predict_true(bf.LoadMem(ea))) {
                   4634:                        CYCLE3(bfchg_ea_less);
                   4635:                } else {
                   4636:                        CYCLE3(bfchg_ea_over);
                   4637:                }
1.1       root     4638:        }
                   4639:        // CCR は操作前のビットフィールドに対して
                   4640:        ACC.move_32(bf.data);
                   4641:        bf.data = ~bf.data;
                   4642:        bf.Store(n);
                   4643: }
                   4644: 
                   4645: // %1110_101111_mmmrrr d.m..rxwp. -34  BFEXTS <ea>{#o:#w},Dn
                   4646: OP_DEF(bfexts)
                   4647: {
                   4648:        uint n = ir & 0x3f;
                   4649:        ir2 = fetch_2();
                   4650:        uint dn = ir2 >> 12;
                   4651: 
                   4652:        acc_bf bf(this);
                   4653:        if (n < 8) {
                   4654:                // BFEXTS Dn{#o:#w},Dn
1.1.1.2   root     4655:                CYCLE3(bfext_dn);
1.1       root     4656:                bf.LoadReg(n);
                   4657:        } else {
                   4658:                // BFEXTS <ea>{#o:#w},Dn
                   4659:                uint32 ea = cea_ctrl();
1.1.1.2   root     4660:                if (__predict_true(bf.LoadMem(ea))) {
                   4661:                        CYCLE3(bfext_ea_less);
                   4662:                } else {
                   4663:                        CYCLE3(bfext_ea_over);
                   4664:                }
1.1       root     4665:        }
                   4666:        // CCR は操作前のビットフィールドに対して
                   4667:        ACC.move_32(bf.data);
                   4668:        // 符号付きシフト
                   4669:        // XXX 負数の右シフト
                   4670:        reg.D[dn] = ((int32)bf.data) >> (32 - bf.width);
                   4671: }
                   4672: 
                   4673: // %1110_110011_mmmrrr d.m..rxw.. -34  BFCLR <ea>{#o:#w}
                   4674: OP_DEF(bfclr)
                   4675: {
                   4676:        uint n = ir & 0x3f;
                   4677:        ir2 = fetch_2();
                   4678: 
                   4679:        acc_bf bf(this);
                   4680:        if (n < 8) {
                   4681:                // BFCLR Dn{#o:#w}
1.1.1.2   root     4682:                CYCLE3(bfclr_dn);
1.1       root     4683:                bf.LoadReg(n);
                   4684:        } else if (n >= 0x3a) {
                   4685:                // BFCLR <ea> に PC 相対(と #imm) はない
                   4686:                op_illegal();
                   4687:        } else {
                   4688:                // BFCLR <ea>{#o:#w}
                   4689:                uint32 ea = cea_ctrl();
1.1.1.2   root     4690:                if (__predict_true(bf.LoadMem(ea))) {
                   4691:                        CYCLE3(bfclr_ea_less);
                   4692:                } else {
                   4693:                        CYCLE3(bfclr_ea_over);
                   4694:                }
1.1       root     4695:        }
                   4696:        // CCR は操作前のビットフィールドに対して
                   4697:        ACC.move_32(bf.data);
                   4698:        bf.data = 0;
                   4699:        bf.Store(n);
                   4700: }
                   4701: 
                   4702: // %1110_110111_mmmrrr d.m..rxwp. -34  BFFFO <ea>{#o:#w},Dn
                   4703: OP_DEF(bfffo)
                   4704: {
                   4705:        uint n = ir & 0x3f;
                   4706:        ir2 = fetch_2();
                   4707:        uint dn = ir2 >> 12;
                   4708: 
                   4709:        acc_bf bf(this);
                   4710:        if (n < 8) {
                   4711:                // BFFFO Dn{#o:#w},Dn
1.1.1.2   root     4712:                CYCLE3(bfffo_dn);
1.1       root     4713:                bf.LoadReg(n);
                   4714:        } else {
                   4715:                // BFFFO <ea>{#o:#w},Dn
                   4716:                uint32 ea = cea_ctrl();
1.1.1.2   root     4717:                if (__predict_true(bf.LoadMem(ea))) {
                   4718:                        CYCLE3(bfffo_ea_less);
                   4719:                } else {
                   4720:                        CYCLE3(bfffo_ea_over);
                   4721:                }
1.1       root     4722:        }
                   4723:        // CCR は操作前のビットフィールドに対して
                   4724:        ACC.move_32(bf.data);
                   4725:        // 1 になっているビットを探す
                   4726:        for (; (int)bf.width-- > 0 && (int32)bf.data >= 0; bf.data <<= 1) {
                   4727:                bf.offset++;
                   4728:        }
                   4729:        reg.D[dn] = bf.offset;
                   4730: }
                   4731: 
                   4732: // %1110_111011_mmmrrr d.m..rxw.. -34  BFSET <ea>{#o:#w}
                   4733: OP_DEF(bfset)
                   4734: {
                   4735:        uint n = ir & 0x3f;
                   4736:        ir2 = fetch_2();
                   4737: 
                   4738:        acc_bf bf(this);
                   4739:        if (n < 8) {
                   4740:                // BFSET Dn{#o:#w}
1.1.1.2   root     4741:                CYCLE3(bfset_dn);
1.1       root     4742:                bf.LoadReg(n);
                   4743:        } else if (n >= 0x3a) {
                   4744:                // BFSET <ea> に PC 相対(と #imm) はない
                   4745:                op_illegal();
                   4746:        } else {
                   4747:                // BFSET <ea>{#o:#w}
                   4748:                uint32 ea = cea_ctrl();
1.1.1.2   root     4749:                if (__predict_true(bf.LoadMem(ea))) {
                   4750:                        CYCLE3(bfset_ea_less);
                   4751:                } else {
                   4752:                        CYCLE3(bfset_ea_over);
                   4753:                }
1.1       root     4754:        }
                   4755:        // CCR は操作前のビットフィールドに対して
                   4756:        ACC.move_32(bf.data);
                   4757:        bf.data = 0xffffffff;
                   4758:        bf.Store(n);
                   4759: }
                   4760: 
                   4761: // %1110_111111_mmmrrr d.m..rxw.. -34  BFINS Dn,<ea>{#o:#w}
                   4762: OP_DEF(bfins)
                   4763: {
                   4764:        uint n = ir & 0x3f;
                   4765:        ir2 = fetch_2();
                   4766:        uint dn = ir2 >> 12;
                   4767: 
                   4768:        acc_bf bf(this);
                   4769:        if (n < 8) {
                   4770:                // BFINS Dm,Dn{#o:#w}
1.1.1.2   root     4771:                CYCLE3(bfins_dn);
1.1       root     4772:                bf.LoadReg(n);
                   4773:        } else if (n >= 0x3a) {
                   4774:                // BFINS Dn,<ea> に PC 相対(と #imm) はない
                   4775:                op_illegal();
                   4776:        } else {
                   4777:                // BFINS Dn,<ea>{#o:#w}
                   4778:                uint32 ea = cea_ctrl();
1.1.1.2   root     4779:                if (__predict_true(bf.LoadMem(ea))) {
                   4780:                        CYCLE3(bfins_ea_less);
                   4781:                } else {
                   4782:                        CYCLE3(bfins_ea_over);
                   4783:                }
1.1       root     4784:        }
                   4785:        bf.data = reg.D[dn] << (32 - bf.width);
                   4786:        // BFINS のみ CCR は操作後のビットフィールドに対して
                   4787:        ACC.move_32(bf.data);
                   4788:        bf.Store(n);
                   4789: }
                   4790: 
1.1.1.3 ! root     4791: // %1111_000nnn_nnnnnn .......... -3-  MMU30_OP
        !          4792: OP_DEF(mmu30)
1.1       root     4793: {
                   4794:        // CPU ごとの virtual 関数になっている。
                   4795:        ops_mmu30();
                   4796: }
                   4797: 
                   4798: // 68030 MMU 命令跡地は 68040 では全部 F ライン例外。
                   4799: void
                   4800: MPU68040Device::ops_mmu30()
                   4801: {
                   4802:        op_illegal();
                   4803: }
                   4804: 
                   4805: // 68030 MMU 命令。
                   4806: void
                   4807: MPU68030Device::ops_mmu30()
                   4808: {
                   4809:        ir2 = fetch_2();
                   4810:        switch ((ir2 >> 8) & 0xff) {
                   4811:         case (0x0800 >> 8):
                   4812:         case (0x0900 >> 8):
                   4813:         case (0x0c00 >> 8):
                   4814:         case (0x0d00 >> 8):
                   4815:         // %000_01n00_000_00000        PMOVE.L <ea>,TTn
                   4816:         // %000_01n01_000_00000        PMOVEFD.L <ea>,TTn
                   4817:         {
1.1.1.2   root     4818:                CYCLE3(pmove_ea_tt);
1.1       root     4819:                uint32 ea = cea_copro();
                   4820:                uint32 data = read_4(ea);
                   4821:                uint n = (ir2 >> 10) & 1;
                   4822:                SetTT(n, data);
1.1.1.3 ! root     4823:                if ((ir2 & 0x0100) == 0) {
        !          4824:                        atc.FlushAll();
        !          4825:                }
        !          4826:                return;
1.1       root     4827:         }
                   4828:         case (0x0a00 >> 8):
                   4829:         case (0x0e00 >> 8):
                   4830:         // %000_01n10_000_00000        PMOVE.L TTn,<ea>
                   4831:         {
1.1.1.2   root     4832:                CYCLE3(pmove_tt_ea);
1.1       root     4833:                uint32 ea = cea_copro();
                   4834:                uint n = (ir2 >> 10) & 1;
                   4835:                write_4(ea, GetTT(n));
1.1.1.3 ! root     4836:                return;
1.1       root     4837:         }
                   4838:         case (0x2000 >> 8):
                   4839:         // %001_00000_000_00000        PLOADW SFC,<ea>
                   4840:         // %001_00000_000_00001        PLOADW DFC,<ea>
                   4841:         // %001_00000_000_01yyy        PLOADW Dy,<ea>
                   4842:         // %001_00000_000_10nnn        PLOADW #<imm>,<ea>
                   4843:         {
1.1.1.2   root     4844:                CYCLE3(pload);
1.1       root     4845: putlog(0, "ploadw");
1.1.1.3 ! root     4846:                ops_mmu30_pload();
        !          4847:                return;
1.1       root     4848:         }
                   4849:         case (0x2200 >> 8):
                   4850:         // %001_00010_000_00000        PLOADR SFC,<ea>
                   4851:         // %001_00010_000_00001        PLOADR DFC,<ea>
                   4852:         // %001_00010_000_01yyy        PLOADR Dy,<ea>
                   4853:         // %001_00010_000_10nnn        PLOADR #<imm>,<ea>
                   4854:         {
1.1.1.2   root     4855:                CYCLE3(pload);
1.1       root     4856: putlog(0, "ploadr");
1.1.1.3 ! root     4857:                ops_mmu30_pload();
        !          4858:                return;
1.1       root     4859:         }
                   4860:         case (0x2400 >> 8):
                   4861:         // %001_00100_000_00000        PFLUSHA
                   4862:         {
1.1.1.2   root     4863:                CYCLE3(pflusha);
1.1.1.3 ! root     4864:                ops_mmu30_pflusha();
        !          4865:                return;
1.1       root     4866:         }
                   4867:         case (0x3000 >> 8):
                   4868:         // %001_10000_nnn_00000        PFLUSH SFC,#<mask>
                   4869:         // %001_10000_nnn_00001        PFLUSH DFC,#<mask>
                   4870:         // %001_10000_nnn_01yyy        PFLUSH Dy,#<mask>
                   4871:         // %001_10000_nnn_10nnn        PFLUSH #<imm>,#<mask>
                   4872:         {
1.1.1.2   root     4873:                CYCLE3(pflush);
1.1.1.3 ! root     4874:                ops_mmu30_pflush();
        !          4875:                return;
1.1       root     4876:         }
                   4877:         case (0x3800 >> 8):
                   4878:         // %001_11000_nnn_00000        PFLUSH SFC,#<mask>,<ea>
                   4879:         // %001_11000_nnn_00001        PFLUSH DFC,#<mask>,<ea>
                   4880:         // %001_11000_nnn_01yyy        PFLUSH Dy,#<mask>,<ea>
                   4881:         // %001_11000_nnn_10nnn        PFLUSH #<imm>,#<mask>,<ea>
                   4882:         {
1.1.1.2   root     4883:                CYCLE3(pflush);
1.1.1.3 ! root     4884:                ops_mmu30_pflush_ea();
        !          4885:                return;
1.1       root     4886:         }
                   4887:         case (0x4000 >> 8):
                   4888:         case (0x4100 >> 8):
                   4889:         // %010_00000_000_00000        PMOVE.L <ea>,TC
                   4890:         // %010_00001_000_00000        PMOVEFD.L <ea>,TC
                   4891:         {
1.1.1.2   root     4892:                CYCLE3(pmove_ea_tc);
1.1       root     4893:                uint32 ea = cea_copro();
                   4894:                uint32 data = read_4(ea);
1.1.1.3 ! root     4895:                if (SetTC(data)) {
        !          4896:                        if ((ir2 & 0x0100) == 0) {
        !          4897:                                atc.FlushAll();
        !          4898:                        }
        !          4899:                } else {
1.1       root     4900:                        Exception(M68K::EXCEP_MMU_CONFIG);
                   4901:                }
1.1.1.3 ! root     4902:                return;
1.1       root     4903:         }
                   4904:         case (0x4200 >> 8):
                   4905:         // %010_00010_000_00000        PMOVE.L TC,<ea>
                   4906:         {
1.1.1.2   root     4907:                CYCLE3(pmove_tc_ea);
1.1       root     4908:                uint32 ea = cea_copro();
                   4909:                write_4(ea, GetTC());
1.1.1.3 ! root     4910:                return;
1.1       root     4911:         }
                   4912:         case (0x4800 >> 8):
                   4913:         case (0x4900 >> 8):
                   4914:         // %010_01000_000_00000        PMOVE.Q <ea>,SRP
                   4915:         // %010_01001_000_00000        PMOVEFD.Q <ea>,SRP
                   4916:         {
1.1.1.2   root     4917:                CYCLE3(pmove_ea_xrp);
1.1       root     4918:                uint32 ea = cea_copro();
                   4919:                uint32 h = read_4(ea);
                   4920:                uint32 l = read_4(ea + 4);
1.1.1.3 ! root     4921:                if (SetSRP(h, l)) {
        !          4922:                        if ((ir2 & 0x0100) == 0) {
        !          4923:                                atc.FlushAll();
        !          4924:                        }
        !          4925:                } else {
1.1       root     4926:                        Exception(M68K::EXCEP_MMU_CONFIG);
                   4927:                }
1.1.1.3 ! root     4928:                return;
1.1       root     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());
1.1.1.3 ! root     4937:                return;
1.1       root     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);
1.1.1.3 ! root     4948:                if (SetCRP(h, l)) {
        !          4949:                        if ((ir2 & 0x0100) == 0) {
        !          4950:                                atc.FlushAll();
        !          4951:                        }
        !          4952:                } else {
1.1       root     4953:                        Exception(M68K::EXCEP_MMU_CONFIG);
                   4954:                }
1.1.1.3 ! root     4955:                return;
1.1       root     4956:         }
                   4957:         case (0x4e00 >> 8):
                   4958:         // %010_01110_000_00000        PMOVE.Q CRP,<ea>
                   4959:         {
1.1.1.2   root     4960:                CYCLE3(pmove_xrp_ea);
1.1       root     4961:                uint32 ea = cea_copro();
                   4962:                write_4(ea,     GetCRPh());
                   4963:                write_4(ea + 4, GetCRPl());
1.1.1.3 ! root     4964:                return;
1.1       root     4965:         }
                   4966:         case (0x6000 >> 8):
                   4967:         // %011_00000_000_00000        PMOVE.W <ea>,MMUSR
                   4968:         {
1.1.1.2   root     4969:                CYCLE3(pmove_ea_mmusr);
1.1       root     4970:                uint32 ea = cea_copro();
                   4971:                uint16 data = read_2(ea);
                   4972:                SetMMUSR(data);
1.1.1.3 ! root     4973:                return;
1.1       root     4974:         }
                   4975:         case (0x6200 >> 8):
                   4976:         // %011_00010_000_00000        PMOVE.W MMUSR,<ea>
                   4977:         {
1.1.1.2   root     4978:                CYCLE3(pmove_mmusr_ea);
1.1       root     4979:                uint32 ea = cea_copro();
                   4980:                write_2(ea, GetMMUSR());
1.1.1.3 ! root     4981:                return;
1.1       root     4982:         }
                   4983:         case (0x8000 >> 8):
                   4984:         case (0x8400 >> 8):
                   4985:         case (0x8800 >> 8):
                   4986:         case (0x8c00 >> 8):
                   4987:         case (0x9000 >> 8):
                   4988:         case (0x9400 >> 8):
                   4989:         case (0x9800 >> 8):
                   4990:         case (0x9c00 >> 8):
                   4991:         // %100_nnn00_000_00000        PTESTW SFC,<ea>,#<level>
                   4992:         // %100_nnn00_000_00001        PTESTW DFC,<ea>,#<level>
                   4993:         // %100_nnn00_000_01yyy        PTESTW Dy,<ea>,#<level>
                   4994:         // %100_nnn00_000_10nnn        PTESTW #<imm>,<ea>,#<level>
                   4995:         {
1.1.1.3 ! root     4996:                ops_mmu30_ptest();
        !          4997:                return;
1.1       root     4998:         }
                   4999:         case (0x8100 >> 8):
                   5000:         case (0x8500 >> 8):
                   5001:         case (0x8900 >> 8):
                   5002:         case (0x8d00 >> 8):
                   5003:         case (0x9100 >> 8):
                   5004:         case (0x9500 >> 8):
                   5005:         case (0x9900 >> 8):
                   5006:         case (0x9d00 >> 8):
                   5007:         // %100_nnn01_nnn_00000        PTESTW SFC,<ea>,#<level>,An
                   5008:         // %100_nnn01_nnn_00001        PTESTW DFC,<ea>,#<level>,An
                   5009:         // %100_nnn01_nnn_01yyy        PTESTW Dy,<ea>,#<level>,An
                   5010:         // %100_nnn01_nnn_10nnn        PTESTW #<imm>,<ea>,#<level>,An
                   5011:         {
1.1.1.3 ! root     5012:                ops_mmu30_ptest();
        !          5013:                return;
1.1       root     5014:         }
                   5015:         case (0x8200 >> 8):
                   5016:         case (0x8600 >> 8):
                   5017:         case (0x8a00 >> 8):
                   5018:         case (0x8e00 >> 8):
                   5019:         case (0x9200 >> 8):
                   5020:         case (0x9600 >> 8):
                   5021:         case (0x9a00 >> 8):
                   5022:         case (0x9e00 >> 8):
                   5023:         // %100_nnn10_000_00000        PTESTR SFC,<ea>,#<level>
                   5024:         // %100_nnn10_000_00001        PTESTR DFC,<ea>,#<level>
                   5025:         // %100_nnn10_000_01yyy        PTESTR Dy,<ea>,#<level>
                   5026:         // %100_nnn10_000_10nnn        PTESTR #<imm>,<ea>,#<level>
                   5027:         {
1.1.1.3 ! root     5028:                ops_mmu30_ptest();
        !          5029:                return;
1.1       root     5030:         }
                   5031:         case (0x8300 >> 8):
                   5032:         case (0x8700 >> 8):
                   5033:         case (0x8b00 >> 8):
                   5034:         case (0x8f00 >> 8):
                   5035:         case (0x9300 >> 8):
                   5036:         case (0x9700 >> 8):
                   5037:         case (0x9b00 >> 8):
                   5038:         case (0x9f00 >> 8):
                   5039:         // %100_nnn11_nnn_00000        PTESTR SFC,<ea>,#<level>,An
                   5040:         // %100_nnn11_nnn_00001        PTESTR DFC,<ea>,#<level>,An
                   5041:         // %100_nnn11_nnn_01yyy        PTESTR Dy,<ea>,#<level>,An
                   5042:         // %100_nnn11_nnn_10nnn        PTESTR #<imm>,<ea>,#<level>,An
                   5043:         {
1.1.1.3 ! root     5044:                ops_mmu30_ptest();
        !          5045:                return;
1.1       root     5046:         }
                   5047:         default:
                   5048:                break;
                   5049:        }
1.1.1.3 ! root     5050:        OP_FUNC(illegal);
1.1       root     5051: }
                   5052: 
                   5053: // 現在の FPCR/FPSR を fe 構造体にコピー。
                   5054: //
                   5055: // fe.fe_{fpcr,fpsr} のほうはこの fpe 用の内部ワークなので破壊してよい。
                   5056: // 命令実行の結果、FPSR レジスタの値を更新する際は fpu_upd_fpsr() を
                   5057: // 呼ぶこと。これを使わず独自に更新する場合は fe.fe_fpframe->fpf_fpsr
                   5058: // (こっちがレジスタ値) と fe.fe_fpsr (FPE 用) を同時に更新すること。
                   5059: // FPCR のほうは FMOVE-to-FPCR 命令以外で変更されることはないはず。
                   5060: #define INIT_FE()      do {    \
                   5061:        fe.fe_fpcr = RegFPCR;   \
                   5062:        fe.fe_fpsr = RegFPSR;   \
                   5063: } while (0)
                   5064: 
                   5065: // ステートを (NULL なら) IDLE に変える。
                   5066: // 6888x では非条件命令、条件命令どちらでも IDLE になる。
                   5067: // 68040 では非条件命令でだけ IDLE になる。
                   5068: // 非条件命令はここでは1ワード目の opclass が 1,2,3 の命令。
                   5069: #define SET_IDLE()     do {    \
                   5070:        if (fpu_state == FPU_STATE_NULL)        \
                   5071:                fpu_state = FPU_STATE_IDLE;     \
                   5072: } while (0)
                   5073: 
                   5074: // %1111_001000_nnnnnn .......... -34  FPGEN
                   5075: OP_DEF(fpgen)
                   5076: {
                   5077:        if (GetFPUType().IsNoFPU()) {
                   5078:                op_illegal();
                   5079:                return;
                   5080:        }
                   5081: 
                   5082:        INIT_FE();
                   5083:        SET_IDLE();
                   5084: 
                   5085:        ir2 = fetch_2();
                   5086:        switch (ir2 >> 13) {
                   5087:         case 0:
                   5088:                fpu_op_fgen_reg();
                   5089:                break;
                   5090:         case 1:
                   5091:                fpu_op_illg();
                   5092:                break;
                   5093:         case 2:
                   5094:                fpu_op_fgen_mem();
                   5095:                break;
                   5096:         case 3:
                   5097:                fpu_op_fmove_to_mem();
                   5098:                break;
                   5099:         case 4:
                   5100:                fpu_op_fmovem_ea2ctl();
                   5101:                break;
                   5102:         case 5:
                   5103:                fpu_op_fmovem_ctl2ea();
                   5104:                break;
                   5105:         case 6:
                   5106:                fpu_op_fmovem_ea2reg();
                   5107:                break;
                   5108:         case 7:
                   5109:                fpu_op_fmovem_reg2ea();
                   5110:                break;
                   5111:        }
                   5112: }
                   5113: 
                   5114: // %1111_001001_mmmrrr d.m+-rxw.. -34  FScc.B <ea>
                   5115: // %1111_001001_001yyy .......... -34  FDBcc Dy,<label>
                   5116: // %1111_001001_111010 .......... -34  FTRAPcc.W #<imm>
                   5117: // %1111_001001_111011 .......... -34  FTRAPcc.L #<imm>
                   5118: // %1111_001001_111100 .......... -34  FTRAPcc
                   5119: OP_DEF(fxcc)
                   5120: {
                   5121:        if (GetFPUType().IsNoFPU()) {
                   5122:                op_illegal();
                   5123:                return;
                   5124:        }
                   5125: 
                   5126:        if ((ir & 077) >= 075) {
                   5127:                op_illegal();
                   5128:                return;
                   5129:        }
                   5130: 
                   5131:        INIT_FE();
                   5132:        if (GetFPUType().Is6888x()) {
                   5133:                SET_IDLE();
                   5134:        }
                   5135: 
                   5136:        // ここまで来ると共通で ir2 に cc が来る。
                   5137:        ir2 = fetch_2();
                   5138:        switch (ir & 077) {
                   5139:         case 010 ... 017:      // FDBcc
                   5140:                fpu_op_fdbcc();
                   5141:                break;
                   5142:         case 000 ... 007:      // FScc
                   5143:         case 020 ... 027:
                   5144:         case 030 ... 037:
                   5145:         case 040 ... 047:
                   5146:         case 050 ... 057:
                   5147:         case 060 ... 067:
                   5148:         case 070 ... 071:
                   5149:                fpu_op_fscc();
                   5150:                break;
                   5151:         case 072:                      // FTRAPcc.W
                   5152:                fpu_op_ftrapcc_w();
                   5153:                break;
                   5154:         case 073:                      // FTRAPcc.L
                   5155:                fpu_op_ftrapcc_l();
                   5156:                break;
                   5157:         case 074:                      // FTRAPcc
                   5158:                fpu_op_ftrapcc();
                   5159:                break;
                   5160:         default:
                   5161:                __unreachable();
                   5162:        }
                   5163: }
                   5164: 
                   5165: // %1111_001010_nnnnnn .......... -34  FBcc.W <label>
                   5166: OP_DEF(fbcc_w)
                   5167: {
                   5168:        if (GetFPUType().IsNoFPU()) {
                   5169:                op_illegal();
                   5170:                return;
                   5171:        }
                   5172: 
                   5173:        INIT_FE();
                   5174:        if (GetFPUType().Is6888x()) {
                   5175:                SET_IDLE();
                   5176:        }
                   5177: 
                   5178:        fpu_op_fbcc_w();
                   5179: }
                   5180: 
                   5181: // %1111_001011_nnnnnn .......... -34  FBcc.L <label>
                   5182: OP_DEF(fbcc_l)
                   5183: {
                   5184:        if (GetFPUType().IsNoFPU()) {
                   5185:                op_illegal();
                   5186:                return;
                   5187:        }
                   5188: 
                   5189:        INIT_FE();
                   5190:        if (GetFPUType().Is6888x()) {
                   5191:                SET_IDLE();
                   5192:        }
                   5193: 
                   5194:        fpu_op_fbcc_l();
                   5195: }
                   5196: 
                   5197: // %1111_001100_mmmrrr ..m.-rxw.. -34  FSAVE <ea>
                   5198: OP_DEF(fsave)
                   5199: {
                   5200:        if (GetFPUType().IsNoFPU()) {
                   5201:                op_illegal();
                   5202:                return;
                   5203:        }
                   5204: 
                   5205:        SUPERVISOR_OP;
                   5206: 
                   5207:        fpu_op_fsave();
                   5208: }
                   5209: 
                   5210: // %1111_001101_mmmrrr ..m+.rxw.. -34  FRESTORE <ea>
                   5211: OP_DEF(frestore)
                   5212: {
                   5213:        if (GetFPUType().IsNoFPU()) {
                   5214:                op_illegal();
                   5215:                return;
                   5216:        }
                   5217: 
                   5218:        SUPERVISOR_OP;
                   5219: 
                   5220:        fpu_op_frestore();
                   5221: }
                   5222: 
                   5223: // %1111_0100nn_001yyy .......... --4  CINVL <caches>,(Ay)
                   5224: // %1111_0100nn_010yyy .......... --4  CINVP <caches>,(Ay)
                   5225: // %1111_0100nn_011000 .......... --4  CINVA <caches>
                   5226: // %1111_0100nn_101yyy .......... --4  CPUSHL <caches>,(Ay)
                   5227: // %1111_0100nn_110yyy .......... --4  CPUSHP <caches>,(Ay)
                   5228: // %1111_0100nn_111000 .......... --4  CPUSHA <caches>
                   5229: OP_DEF(cinv)
                   5230: {
                   5231:        if (mpu_type != m680x0MPUType::M68040) {
                   5232:                op_illegal();
                   5233:                return;
                   5234:        }
                   5235: //     putlog(1, "cinv*/cpush* (NOT IMPLEMENTED)");
                   5236: }
                   5237: 
                   5238: // %1111_010100_mmmrrr ..m.-rxw.. 23-  cpSAVE
                   5239: // %1111_010100_000yyy .......... --4  PFLUSHN (Ay)
                   5240: // %1111_010100_001yyy .......... --4  PFLUSH (Ay)
                   5241: // %1111_010100_010000 .......... --4  PFLUSHAN
                   5242: // %1111_010100_011000 .......... --4  PFLUSHA
                   5243: OP_DEF(pflush)
                   5244: {
                   5245:        // CPU ごとの virtual 関数になっている。
                   5246:        ops_mmu40_pflush();
                   5247: }
                   5248: 
                   5249: // 68030 では 68040 MMU 命令の位置は全部 cpSAVE。
                   5250: void
                   5251: MPU68030Device::ops_mmu40_pflush()
                   5252: {
                   5253:        op_cpsave();
                   5254: }
                   5255: 
                   5256: // 68040 MMU 命令。
                   5257: void
                   5258: MPU68040Device::ops_mmu40_pflush()
                   5259: {
                   5260:        SUPERVISOR_OP;
                   5261: 
                   5262:        // DFC は 1,2,5,6 の場合のみ有効で、0,3,4,7 なら動作不定。
                   5263:        // 68000PRM.pdf, p6-35。
                   5264:        // ここでは FC2 だけで判定する。
                   5265: 
                   5266:        switch (ir & 077) {
                   5267:         case 000 ... 007:      // PFLUSHN (Ay)
                   5268:         {
1.1.1.2   root     5269:                CYCLE(11);
1.1       root     5270:                busaddr addr = busaddr(RegAY) | reg.dfc;
1.1.1.3 ! root     5271:                atc_inst->Flush(addr, true);
        !          5272:                atc_data->Flush(addr, true);
        !          5273:                return;
1.1       root     5274:         }
                   5275: 
                   5276:         case 010 ... 017:      // PFLUSH (Ay)
                   5277:         {
1.1.1.2   root     5278:                CYCLE(11);
1.1       root     5279:                busaddr addr = busaddr(RegAY) | reg.dfc;
1.1.1.3 ! root     5280:                atc_inst->Flush(addr, false);
        !          5281:                atc_data->Flush(addr, false);
        !          5282:                return;
1.1       root     5283:         }
                   5284: 
                   5285:         case 020:                      // PFLUSHAN
                   5286:         {
1.1.1.2   root     5287:                CYCLE(27);
1.1       root     5288:                bool s = reg.dfc.IsSuper();
1.1.1.3 ! root     5289:                atc_inst->Flush(s, true);
        !          5290:                atc_data->Flush(s, true);
        !          5291:                return;
1.1       root     5292:         }
                   5293: 
                   5294:         case 030:                      // PFLUSHA
                   5295:         {
1.1.1.2   root     5296:                CYCLE3(pflusha);
1.1       root     5297:                bool s = reg.dfc.IsSuper();
1.1.1.3 ! root     5298:                atc_inst->Flush(s, false);
        !          5299:                atc_data->Flush(s, false);
        !          5300:                return;
1.1       root     5301:         }
                   5302: 
                   5303:         default:
1.1.1.3 ! root     5304:                break;
1.1       root     5305:        }
1.1.1.3 ! root     5306:        op_illegal();
1.1       root     5307: }
                   5308: 
                   5309: // %1111_010101_mmmrrr ..m+.rxwp. 23-  cpRESTORE
                   5310: // %1111_010101_001yyy .......... --4  PTESTW (Ay)
                   5311: // %1111_010101_101yyy .......... --4  PTESTR (Ay)
                   5312: OP_DEF(ptest)
                   5313: {
                   5314:        if (mpu_type != m680x0MPUType::M68040) {
                   5315:                op_cprestore();
                   5316:                return;
                   5317:        }
1.1.1.2   root     5318:        //CYCLE(25);
1.1       root     5319:        OP_FUNC(unimpl);
                   5320: }
                   5321: 
                   5322: // %1111_011000_000yyy .......... --4  MOVE16 (Ay)+,xxx.L
                   5323: // %1111_011000_001yyy .......... --4  MOVE16 xxx.L,(Ay)+
                   5324: // %1111_011000_010yyy .......... --4  MOVE16 (Ay),xxx.L
                   5325: // %1111_011000_011yyy .......... --4  MOVE16 xxx.L,(Ay)
                   5326: // %1111_011000_100yyy .......... --4  MOVE16 (Ay)+,(An)+
                   5327: OP_DEF(move16)
                   5328: {
                   5329:        if (mpu_type != m680x0MPUType::M68040) {
                   5330:                op_illegal();
                   5331:                return;
                   5332:        }
                   5333:        OP_FUNC(unimpl);
                   5334: }
                   5335: 
                   5336: // %1111_011100_mmmrrr ..m.-rxw.. 23-  cpSAVE
                   5337: // %1111_100100_mmmrrr ..m.-rxw.. 23-  cpSAVE
                   5338: // %1111_101100_mmmrrr ..m.-rxw.. 23-  cpSAVE
                   5339: // %1111_110100_mmmrrr ..m.-rxw.. 23-  cpSAVE
                   5340: // %1111_111100_mmmrrr ..m.-rxw.. 23-  cpSAVE
                   5341: OP_DEF(cpsave)
                   5342: {
                   5343:        // 020/030 では、(第1ワードが?) 有効な命令パターンの場合
                   5344:        // まず特権チェックを行う。
                   5345:        // cpSAVE の場合先に CIR で問い合わせて、その後 EA を評価すると書いて
                   5346:        // あるように読める (68020 本 p.104) ので、コプロセッサがいない場合は
                   5347:        // EA は評価しなさそう。
                   5348:        // -(An) はコプロセッサがいなければ変化しないような気がする。
                   5349:        // EA のパターンが無効なら F ライン例外になる。
                   5350:        // cpID=6,7 はユーザ用とあるが cpSAVE は影響を受けるかどうか。
                   5351:        // 040 ではコプロセッサプロトコル自体ないので全部 F ライン例外になる?
                   5352:        //
                   5353:        // ただし、Human68k モードではその特権判定よりも先んじて不当命令に
                   5354:        // ならなければいけない。
                   5355:        // Human68k モードでは F ライン命令は例外を起こすのではなく、命令内部で
                   5356:        // 直接ホストのコールバックを実行しているため、ゲスト側の特権違反ハンドラ
                   5357:        // に来たものを F ライン例外へ回すというような処理は出来ないため。
                   5358:        if (fline_callback == NULL && mpu_type == m680x0MPUType::M68030) {
                   5359:                switch (ir & 077) {
                   5360:                 case 020 ... 027:      // m:(An)
                   5361:                 case 040 ... 047:      // -:-(An)
                   5362:                 case 050 ... 057:      // r:d16(An)
                   5363:                 case 060 ... 067:      // x:d8(An,IX)
                   5364:                 case 070 ... 071:      // w:Abs
                   5365:                        SUPERVISOR_OP;
                   5366:                        // コプロセッサがいないので EA をフェッチせず終了のはず。
                   5367:                        break;
                   5368:                 default:
                   5369:                        break;
                   5370:                }
                   5371:        }
                   5372:        op_illegal();
                   5373: }
                   5374: 
                   5375: // %1111_011101_mmmrrr ..m+.rxwp. 23-  cpRESTORE
                   5376: // %1111_100101_mmmrrr ..m+.rxwp. 23-  cpRESTORE
                   5377: // %1111_101101_mmmrrr ..m+.rxwp. 23-  cpRESTORE
                   5378: // %1111_110101_mmmrrr ..m+.rxwp. 23-  cpRESTORE
                   5379: // %1111_111101_mmmrrr ..m+.rxwp. 23-  cpRESTORE
                   5380: OP_DEF(cprestore)
                   5381: {
                   5382:        // すぐ上の cpsave 内のコメント参照。
                   5383:        // cpRESTORE の場合先に1ロングワード読んでみて、その後コプロセッサに
                   5384:        // 通信するので、コプロセッサがいなくても読み込みは発生する。
                   5385:        // See XEiJ/misc/flinebuserror.x
                   5386:        if (fline_callback == NULL && mpu_type == m680x0MPUType::M68030) {
                   5387:                switch (ir & 077) {
                   5388:                 case 020 ... 027:      // m:(An)
                   5389:                 case 030 ... 037:      // +:(An)+
                   5390:                 case 050 ... 057:      // r:d16(An)
                   5391:                 case 060 ... 067:      // x:d8(An,IX)
                   5392:                 case 070 ... 071:      // w:Abs
                   5393:                 case 072 ... 073:      // p:d8(PC,IX)
                   5394:                 {
                   5395:                        SUPERVISOR_OP;
                   5396:                        uint32 ea = cea_fpu(4);
                   5397:                        read_4(ea);
                   5398:                        break;
                   5399:                 }
                   5400:                 default:
                   5401:                        break;
                   5402:                }
                   5403:        }
                   5404:        op_illegal();
                   5405: }
                   5406: 
1.1.1.2   root     5407: // %1111_010110_001nnn .......... --6  PLPAW (An)
                   5408: // %1111_010111_001nnn .......... --6  PLPAR (An)
                   5409: OP_DEF(plpa)
                   5410: {
                   5411:        op_illegal();
                   5412: }
                   5413: 
                   5414: // %1111_100000_000000 .......... --6  LPSTOP
                   5415: OP_DEF(lpstop)
                   5416: {
                   5417:        op_illegal();
                   5418: }
                   5419: 
1.1       root     5420: // illegal (or not-assigned) instructions
                   5421: OP_DEF(illegal)
                   5422: {
                   5423:        // ILLEGAL 命令と F ライン命令と不当命令パターンがすべてここに来る。
                   5424:        // catch 内からも呼ばれるので、ここで C++ の例外をスローしてはいけない。
                   5425: 
                   5426:        if ((ir & 0xf000) == 0xf000) {
                   5427:                // F系列命令
1.1.1.2   root     5428:                CYCLE3(fline);
1.1       root     5429:                if (fline_callback) {
                   5430:                        if (fline_callback(this, fline_arg)) {
                   5431:                                return;
                   5432:                        }
                   5433:                }
1.1.1.2   root     5434:                ExceptionFLine();
1.1       root     5435:        } else {
                   5436:                // 不当命令
1.1.1.2   root     5437:                CYCLE3(illegal);
1.1       root     5438:                Exception(M68K::EXCEP_ILLEGAL);
                   5439:        }
                   5440: }

unix.superglobalmegacorp.com

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