--- nono/m680x0/m680x0ops.cpp 2026/04/29 17:05:31 1.1 +++ nono/m680x0/m680x0ops.cpp 2026/04/29 17:05:40 1.1.1.2 @@ -7,6 +7,7 @@ #include "mpu680x0.h" #include "m680x0acc.h" #include "m680x0bitfield.h" +#include "m680x0cycle.h" #include "m68040mmu.h" #define OP_DEF(name) void __CONCAT(MPU680x0Device::op_,name)() @@ -30,7 +31,7 @@ // 特権違反例外のスタックに積む PC は違反を起こした命令先頭。 #define SUPERVISOR_OP do { \ if (!IsSuper()) { \ - CYCLE2(18, 20); \ + CYCLE3(excep_priv); \ Exception(M68K::EXCEP_PRIV); \ return; \ } \ @@ -45,17 +46,17 @@ OP_DEF(ori_b) uint32 src = fetch_2() & 0xff; if (n < 8) { // ORI.B #,Dn - CYCLE(2); + CYCLE3(ori_dn); uint32 dst = (reg.D[n] & 0xff) | src; ACC.move_8(dst); reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else if (n == 0b111100) { // ORI.B #,CCR - CYCLE2(12, 14); + CYCLE3(ori_ccr); CCR.Set(CCR.Get() | src); } else { // ORI.B #, - CYCLE2(3, 4); + CYCLE3(ori_ea); uint32 ea = cea_data_1(); uint32 dst = read_1(ea); dst |= src; @@ -72,7 +73,7 @@ OP_DEF(ori_w) if (n < 8) { // ORI.W #,Dn - CYCLE(2); + CYCLE3(ori_dn); uint32 src = fetch_2(); uint32 dst = (reg.D[n] & 0xffff) | src; ACC.move_16(dst); @@ -80,12 +81,12 @@ OP_DEF(ori_w) } else if (n == 0b111100) { // ORI.W #,SR SUPERVISOR_OP; - CYCLE2(12, 14); + CYCLE3(ori_sr); uint32 src = fetch_2(); SetSR(GetSR() | src); } else { // ORI.W #, - CYCLE2(3, 4); + CYCLE3(ori_ea); uint32 src = fetch_2(); uint32 ea = cea_data_2(); uint32 dst = read_2(ea); @@ -103,12 +104,12 @@ OP_DEF(ori_l) uint32 src = fetch_4(); if (n < 8) { // ORI.L #,Dn - CYCLE(2); + CYCLE3(ori_dn); reg.D[n] |= src; ACC.move_32(reg.D[n]); } else { // ORI.L #, - CYCLE2(3, 4); + CYCLE3(ori_ea); uint32 ea = cea_data_4(); uint32 dst = read_4(ea); dst |= src; @@ -145,14 +146,14 @@ OP_DEF(cmp2chk2_b) if ((ir2 & 0x0800)) { // CHK2 で条件を満たしていれば例外 if (reg.ccr.CondCS()) { - CYCLE2(40, 42); + CYCLE3(chk2_excep_max); Exception(M68K::EXCEP_CHK); } else { - CYCLE(18); + CYCLE3(chk2); } } else { // CMP2 - CYCLE(20); + CYCLE3(cmp2_max); } } @@ -166,7 +167,7 @@ MPU680x0Device::ops_movep() bool size_long = ((ir & 0x40) != 0); bool reg2mem = ((ir & 0x80) != 0); - CYCLE(14); + CYCLE3(movep); if (reg2mem) { // Dx -> memory @@ -214,7 +215,7 @@ OP_DEF(btst_dn_ea) if (n < 8) { // BTST.L Dx,Dy - CYCLE(4); + CYCLE3(btst_dn); uint bit = (RegDX & 31); ACC.btst(RegDY, bit); } else if (n < 16) { @@ -222,7 +223,7 @@ OP_DEF(btst_dn_ea) ops_movep(); } else { // BTST.B Dx, - CYCLE(4); + CYCLE3(btst_dn); uint bit = (RegDX & 7); uint32 data = fea_data_1(); ACC.btst(data, bit); @@ -238,7 +239,7 @@ OP_DEF(bchg_dn_ea) if (n < 8) { // BCHG.L Dx,Dy - CYCLE(6); + CYCLE3(bchg_dn); uint bit = (RegDX & 31); RegDY = ACC.bchg(RegDY, bit); } else if (n < 16) { @@ -246,7 +247,7 @@ OP_DEF(bchg_dn_ea) ops_movep(); } else { // BCHG.B Dx, - CYCLE(6); + CYCLE3(bchg_dn); uint bit = (RegDX & 7); uint32 ea = cea_data_1(); uint32 data = read_1(ea); @@ -264,7 +265,7 @@ OP_DEF(bclr_dn_ea) if (n < 8) { // BCLR.L Dx,Dy - CYCLE(6); + CYCLE3(bclr_dn); uint bit = (RegDX & 31); RegDY = ACC.bclr(RegDY, bit); } else if (n < 16) { @@ -272,7 +273,7 @@ OP_DEF(bclr_dn_ea) ops_movep(); } else { // BCLR.B Dx, - CYCLE(6); + CYCLE3(bclr_dn); uint bit = (RegDX & 7); uint32 ea = cea_data_1(); uint32 data = read_1(ea); @@ -290,7 +291,7 @@ OP_DEF(bset_dn_ea) if (n < 8) { // BSET.L Dx,Dy - CYCLE(6); + CYCLE3(bset_dn); uint bit = (RegDX & 31); RegDY = ACC.bset(RegDY, bit); } else if (n < 16) { @@ -298,7 +299,7 @@ OP_DEF(bset_dn_ea) ops_movep(); } else { // BSET.B Dx, - CYCLE(6); + CYCLE3(bset_dn); uint bit = (RegDX & 7); uint32 ea = cea_data_1(); uint32 data = read_1(ea); @@ -316,18 +317,18 @@ OP_DEF(andi_b) uint32 src = fetch_2() & 0xff; if (n < 8) { // ANDI.B #,Dn - CYCLE(2); + CYCLE3(andi_dn); uint32 dst = reg.D[n] & 0xff; dst &= src; ACC.move_8(dst); reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else if (n == 0b111100) { // ANDI.B #,CCR - CYCLE2(12, 14); + CYCLE3(andi_ccr); CCR.Set(CCR.Get() & src); } else { // ANDI.B #, - CYCLE2(3, 4); + CYCLE3(andi_ea); uint32 ea = cea_data_1(); uint32 dst = read_1(ea); dst &= src; @@ -344,7 +345,7 @@ OP_DEF(andi_w) if (n < 8) { // ANDI.W #,Dn - CYCLE(2); + CYCLE3(andi_dn); uint32 src = fetch_2(); uint32 dst = reg.D[n] & 0xffff; dst &= src; @@ -353,12 +354,12 @@ OP_DEF(andi_w) } else if (n == 0b111100) { // ANDI.W #,SR SUPERVISOR_OP; - CYCLE2(12, 14); + CYCLE3(andi_sr); uint32 src = fetch_2(); SetSR(GetSR() & src); } else { // ANDI.W #, - CYCLE2(3, 4); + CYCLE3(andi_ea); uint32 src = fetch_2(); uint32 ea = cea_data_2(); uint32 dst = read_2(ea); @@ -376,12 +377,12 @@ OP_DEF(andi_l) uint32 src = fetch_4(); if (n < 8) { // ANDI.L #,Dn - CYCLE(2); + CYCLE3(andi_dn); reg.D[n] &= src; ACC.move_32(reg.D[n]); } else { // ANDI.L #, - CYCLE2(3, 4); + CYCLE3(andi_ea); uint32 ea = cea_data_4(); uint32 dst = read_4(ea); dst &= src; @@ -418,14 +419,14 @@ OP_DEF(cmp2chk2_w) if ((ir2 & 0x0800)) { // CHK2 で条件を満たしていれば例外 if (reg.ccr.CondCS()) { - CYCLE2(40, 42); + CYCLE3(chk2_excep_max); Exception(M68K::EXCEP_CHK); } else { - CYCLE(18); + CYCLE3(chk2); } } else { // CMP2 - CYCLE(20); + CYCLE3(cmp2_max); } } @@ -437,13 +438,13 @@ OP_DEF(subi_b) uint32 src = fetch_2() & 0xff; if (n < 8) { // SUBI.B #,Dn - CYCLE(2); + CYCLE3(subi_dn); uint32 dst = reg.D[n] & 0xff; dst = ACC.sub_8(src, dst); reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else { // SUBI.B #, - CYCLE2(3, 4); + CYCLE3(subi_ea); uint32 ea = cea_data_1(); uint32 dst = read_1(ea); dst = ACC.sub_8(src, dst); @@ -459,13 +460,13 @@ OP_DEF(subi_w) uint32 src = fetch_2(); if (n < 8) { // SUBI.W #,Dn - CYCLE(2); + CYCLE3(subi_dn); uint32 dst = reg.D[n] & 0xffff; dst = ACC.sub_16(src, dst); reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else { // SUBI.W #, - CYCLE2(3, 4); + CYCLE3(subi_ea); uint32 ea = cea_data_2(); uint32 dst = read_2(ea); dst = ACC.sub_16(src, dst); @@ -481,11 +482,11 @@ OP_DEF(subi_l) uint32 src = fetch_4(); if (n < 8) { // SUBI.L #,Dn - CYCLE(2); + CYCLE3(subi_dn); reg.D[n] = ACC.sub_32(src, reg.D[n]); } else { // SUBI.L #, - CYCLE2(3, 4); + CYCLE3(subi_ea); uint32 ea = cea_data_4(); uint32 dst = read_4(ea); dst = ACC.sub_32(src, dst); @@ -513,14 +514,14 @@ OP_DEF(cmp2chk2_l) if ((ir2 & 0x0800)) { // CHK2 で条件を満たしていれば例外 if (reg.ccr.CondCS()) { - CYCLE2(40, 42); + CYCLE3(chk2_excep_max); Exception(M68K::EXCEP_CHK); } else { - CYCLE(18); + CYCLE3(chk2); } } else { // CMP2 - CYCLE(20); + CYCLE3(cmp2_max); } } @@ -532,13 +533,13 @@ OP_DEF(addi_b) uint32 src = fetch_2() & 0xff; if (n < 8) { // ADDI.B #,Dn - CYCLE(2); + CYCLE3(addi_dn); uint32 dst = reg.D[n] & 0xff; dst = ACC.add_8(src, dst); reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else { // ADDI.B #, - CYCLE2(3, 4); + CYCLE3(addi_ea); uint32 ea = cea_data_1(); uint32 dst = read_1(ea); dst = ACC.add_8(src, dst); @@ -554,13 +555,13 @@ OP_DEF(addi_w) uint32 src = fetch_2(); if (n < 8) { // ADDI.W #,Dn - CYCLE(2); + CYCLE3(addi_dn); uint32 dst = reg.D[n] & 0xffff; dst = ACC.add_16(src, dst); reg.D[n] = (reg.D[n] & 0xffff0000) | dst; } else { // ADDI.W #, - CYCLE2(3, 4); + CYCLE3(addi_ea); uint32 ea = cea_data_2(); uint32 dst = read_2(ea); dst = ACC.add_16(src, dst); @@ -576,11 +577,11 @@ OP_DEF(addi_l) uint32 src = fetch_4(); if (n < 8) { // ADDI.L #,Dn - CYCLE(2); + CYCLE3(addi_dn); reg.D[n] = ACC.add_32(src, reg.D[n]); } else { // ADDI.L #, - CYCLE2(3, 4); + CYCLE3(addi_ea); uint32 ea = cea_data_4(); uint32 dst = read_4(ea); dst = ACC.add_32(src, dst); @@ -603,7 +604,7 @@ OP_DEF(btst_imm_ea) if (n < 8) { // BTST.L #,Dy - CYCLE(4); + CYCLE3(btst_imm); uint bit = fetch_2() & 31; ACC.btst(RegDY, bit); } else if (n == 0x3c) { @@ -611,7 +612,7 @@ OP_DEF(btst_imm_ea) op_illegal(); } else { // BTST.B #, - CYCLE(4); + CYCLE3(btst_imm); uint bit = fetch_2() & 7; uint32 data = fea_data_1(); ACC.btst(data, bit); @@ -626,7 +627,7 @@ OP_DEF(bchg_imm_ea) if (n < 8) { // BCHG.L #,Dy - CYCLE(6); + CYCLE3(bchg_imm); uint bit = fetch_2() & 31; RegDY = ACC.bchg(RegDY, bit); } else if (n == 0x3c) { @@ -634,7 +635,7 @@ OP_DEF(bchg_imm_ea) op_illegal(); } else { // BCHG.B #, - CYCLE(6); + CYCLE3(bchg_imm); uint bit = fetch_2() & 7; uint32 ea = cea_data_1(); uint32 data = read_1(ea); @@ -651,7 +652,7 @@ OP_DEF(bclr_imm_ea) if (n < 8) { // BCLR.L #,Dy - CYCLE(6); + CYCLE3(bclr_imm); uint bit = fetch_2() & 31; RegDY = ACC.bclr(RegDY, bit); } else if (n == 0x3c) { @@ -659,7 +660,7 @@ OP_DEF(bclr_imm_ea) op_illegal(); } else { // BCLR.B #, - CYCLE(6); + CYCLE3(bclr_imm); uint bit = fetch_2() & 7; uint32 ea = cea_data_1(); uint32 data = read_1(ea); @@ -676,7 +677,7 @@ OP_DEF(bset_imm_ea) if (n < 8) { // BSET.L #,Dy - CYCLE(6); + CYCLE3(bset_imm); uint bit = fetch_2() & 31; RegDY = ACC.bset(RegDY, bit); } else if (n == 0x3c) { @@ -684,7 +685,7 @@ OP_DEF(bset_imm_ea) op_illegal(); } else { // BSET.B #, - CYCLE(6); + CYCLE3(bset_imm); uint bit = fetch_2() & 7; uint32 ea = cea_data_1(); uint32 data = read_1(ea); @@ -702,17 +703,17 @@ OP_DEF(eori_b) uint32 src = fetch_2() & 0xff; if (n < 8) { // EORI.B #,Dn - CYCLE(2); + CYCLE3(eori_dn); uint32 dst = (reg.D[n] & 0xff) ^ src; ACC.move_8(dst); reg.D[n] = (reg.D[n] & 0xffffff00) | dst; } else if (n == 0b111100) { // EORI.B #,CCR - CYCLE2(12, 14); + CYCLE3(eori_ccr); CCR.Set(CCR.Get() ^ src); } else { // EORI.B #, - CYCLE2(3, 4); + CYCLE3(eori_ea); uint32 ea = cea_data_1(); uint32 dst = read_1(ea); dst ^= src; @@ -729,7 +730,7 @@ OP_DEF(eori_w) if (n < 8) { // EORI.W #,Dn - CYCLE(2); + CYCLE3(eori_dn); uint32 src = fetch_2(); uint32 dst = (reg.D[n] & 0xffff) ^ src; ACC.move_16(dst); @@ -737,12 +738,12 @@ OP_DEF(eori_w) } else if (n == 0b111100) { // EORI.W #,SR SUPERVISOR_OP; - CYCLE2(12, 14); + CYCLE3(eori_sr); uint32 src = fetch_2(); SetSR(GetSR() ^ src); } else { // EORI.W #, - CYCLE2(3, 4); + CYCLE3(eori_ea); uint32 src = fetch_2(); uint32 ea = cea_data_2(); uint32 dst = read_2(ea); @@ -760,12 +761,12 @@ OP_DEF(eori_l) uint32 src = fetch_4(); if (n < 8) { // EORI.L #,Dn - CYCLE(2); + CYCLE3(eori_dn); reg.D[n] ^= src; ACC.move_32(reg.D[n]); } else { // EORI.L #, - CYCLE2(3, 4); + CYCLE3(eori_ea); uint32 ea = cea_data_4(); uint32 dst = read_4(ea); dst ^= src; @@ -788,11 +789,11 @@ OP_DEF(cas_b) ACC.cmp_8(dc, dst); if (CCR.IsZ()) { // 等しければ、Du -> dst - CYCLE(13); + CYCLE3(cas_eq); write_1(ea, du); } else { // そうでなければ、dst -> Dc - CYCLE(11); + CYCLE3(cas_ne); reg.D[c] = (reg.D[c] & 0xffffff00) | dst; } } @@ -807,7 +808,7 @@ OP_DEF(cmpi_b) op_illegal(); return; } - CYCLE(2); + CYCLE3(cmpi); uint32 src = fetch_2() & 0xff; uint32 dst = fea_data_1(); ACC.cmp_8(src, dst); @@ -823,7 +824,7 @@ OP_DEF(cmpi_w) op_illegal(); return; } - CYCLE(2); + CYCLE3(cmpi); uint32 src = fetch_2(); uint32 dst = fea_data_2(); ACC.cmp_16(src, dst); @@ -839,7 +840,7 @@ OP_DEF(cmpi_l) op_illegal(); return; } - CYCLE(2); + CYCLE3(cmpi); uint32 src = fetch_4(); uint32 dst = fea_data_4(); ACC.cmp_32(src, dst); @@ -875,13 +876,13 @@ OP_DEF(cas_w) ACC.cmp_16(dc2, dst2); if (CCR.IsZ()) { // 更新オペランド -> デスティネーション - CYCLE2(0, 2); // これは成功時の追加分 + CYCLE3(cas2_true_inc); // これは成功時の追加分 write_2(ea1, du1); write_2(ea2, du2); } } // デスティネーション -> 比較オペランド - CYCLE(24); // 本当はこれは最大値 + CYCLE3(cas2_max); reg.D[c1] = (reg.D[c1] & 0xffff0000) | dst1; reg.D[c2] = (reg.D[c2] & 0xffff0000) | dst2; } else { @@ -897,11 +898,11 @@ OP_DEF(cas_w) ACC.cmp_16(dc, dst); if (CCR.IsZ()) { // 等しければ、Du -> dst - CYCLE(13); + CYCLE3(cas_eq); write_2(ea, du); } else { // そうでなければ、dst -> Dc - CYCLE(11); + CYCLE3(cas_ne); reg.D[c] = (reg.D[c] & 0xffff0000) | dst; } } @@ -944,18 +945,19 @@ OP_DEF(moves_b) ea = cea_data_1(); if ((ir2 & 0x0800) == 0) { // ,Rn - CYCLE(7); busaddr sfc = translate_fc40(reg.sfc); busaddr addr = busaddr(ea) | sfc | BusAddr::Size1; data = read_data(addr); if (n < 8) { // Dn reg.D[n] = (reg.D[n] & 0xffffff00) | data; + CYCLE3(moves_ea_dn); } else { // An reg.R[n] = (int32)(int8)data; + CYCLE3(moves_ea_an); } } else { // Rn, - CYCLE2(5, 6); + CYCLE3(moves_rn_ea); busaddr dfc = translate_fc40(reg.dfc); busaddr addr = busaddr(ea) | dfc | BusAddr::Size1; data = reg.R[n] & 0xff; @@ -982,18 +984,19 @@ OP_DEF(moves_w) ea = cea_data_2(); if ((ir2 & 0x0800) == 0) { // ,Rn - CYCLE(7); busaddr sfc = translate_fc40(reg.sfc); busaddr addr = busaddr(ea) | sfc | BusAddr::Size2; data = read_data(addr); if (n < 8) { // Dn reg.D[n] = (reg.D[n] & 0xffff0000) | data; + CYCLE3(moves_ea_dn); } else { // An reg.R[n] = (int32)(int16)data; + CYCLE3(moves_ea_an); } } else { // Rn, - CYCLE2(5, 6); + CYCLE3(moves_rn_ea); busaddr dfc = translate_fc40(reg.dfc); busaddr addr = busaddr(ea) | dfc | BusAddr::Size2; data = reg.R[n] & 0xffff; @@ -1020,14 +1023,18 @@ OP_DEF(moves_l) ea = cea_data_4(); if ((ir2 & 0x0800) == 0) { // ,Rn - CYCLE(7); busaddr sfc = translate_fc40(reg.sfc); busaddr addr = busaddr(ea) | sfc | BusAddr::Size4; data = read_data(addr); reg.R[n] = data; + if (n < 8) { + CYCLE3(moves_ea_dn); + } else { + CYCLE3(moves_ea_an); + } } else { // Rn, - CYCLE2(5, 6); + CYCLE3(moves_rn_ea); busaddr dfc = translate_fc40(reg.dfc); busaddr addr = busaddr(ea) | dfc | BusAddr::Size4; data = reg.R[n]; @@ -1065,13 +1072,13 @@ OP_DEF(cas_l) ACC.cmp_32(dc2, dst2); if (CCR.IsZ()) { // 更新オペランド -> デスティネーション - CYCLE2(0, 2); // これは成功時の追加分 + CYCLE3(cas2_true_inc); // これは成功時の追加分 write_4(ea1, du1); write_4(ea2, du2); } } // デスティネーション -> 比較オペランド - CYCLE(24); // 本当はこれは最大値 + CYCLE3(cas2_max); reg.D[c1] = dst1; reg.D[c2] = dst2; } else { @@ -1087,11 +1094,11 @@ OP_DEF(cas_l) ACC.cmp_32(dc, dst); if (CCR.IsZ()) { // 等しければ、Du -> dst - CYCLE(13); + CYCLE3(cas_eq); write_4(ea, du); } else { // そうでなければ、dst -> Dc - CYCLE(11); + CYCLE3(cas_ne); reg.D[c] = dst; } } @@ -1100,7 +1107,7 @@ OP_DEF(cas_l) // %0001_xxx000_mmmrrr d.m+-rxwpi 034 MOVE.B ,Dx OP_DEF(move_b_ea_dn) { - CYCLE(2); + CYCLE3(move_ea_dn); uint32 data = fea_all_1(); ACC.move_8(data); RegDX = (RegDX & 0xffffff00) | data; @@ -1109,10 +1116,10 @@ OP_DEF(move_b_ea_dn) // %0001_xxx010_mmmrrr d.m+-rxwpi 034 MOVE.B ,(Ax) OP_DEF(move_b_ea_anin) { - // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anin); uint32 data = fea_all_1(); - uint32 ea = cea_anin(RegIRX); + uint32 ea = internal_ea_anin(RegIRX); ACC.move_8(data); write_1(ea, data); } @@ -1120,12 +1127,12 @@ OP_DEF(move_b_ea_anin) // %0001_xxx011_mmmrrr d.m+-rxwpi 034 MOVE.B ,(Ax)+ OP_DEF(move_b_ea_anpi) { - // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anpi); uint32 data = fea_all_1(); // (An)+,(Ax)+ が n==x なら2回目はセーブしてはいけない。 save_reg_pi_if(RegIRX); - uint32 ea = cea_anpi_1(RegIRX); + uint32 ea = internal_ea_anpi_1(RegIRX); ACC.move_8(data); write_1(ea, data); } @@ -1133,12 +1140,12 @@ OP_DEF(move_b_ea_anpi) // %0001_xxx100_mmmrrr d.m+-rxwpi 034 MOVE.B ,-(Ax) OP_DEF(move_b_ea_anpd) { - // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anpd); uint32 data = fea_all_1(); // -(An),-(Ax) が n==x なら2回目はセーブしてはいけない。 save_reg_pd_if(RegIRX); - uint32 ea = cea_anpd_1(RegIRX); + uint32 ea = internal_ea_anpd_1(RegIRX); ACC.move_8(data); write_1(ea, data); } @@ -1146,9 +1153,10 @@ OP_DEF(move_b_ea_anpd) // %0001_xxx101_mmmrrr d.m+-rxwpi 034 MOVE.B ,d16(Ax) OP_DEF(move_b_ea_andi) { - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_andi); uint32 data = fea_all_1(); - uint32 ea = cea_andi(RegIRX); + uint32 ea = internal_ea_andi(RegIRX); ACC.move_8(data); write_1(ea, data); } @@ -1156,10 +1164,10 @@ OP_DEF(move_b_ea_andi) // %0001_xxx110_mmmrrr d.m+-rxwpi 034 MOVE.B ,(Ax,IX) OP_DEF(move_b_ea_anix) { - // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) - CYCLE2(16, 18); + // dst 分込み。 + CYCLE3(move_ea_anix); uint32 data = fea_all_1(); - uint32 ea = cea_anix(RegIRX); + uint32 ea = internal_ea_anix(RegIRX); ACC.move_8(data); write_1(ea, data); } @@ -1167,9 +1175,10 @@ OP_DEF(move_b_ea_anix) // %0001_000111_mmmrrr d.m+-rxwpi 034 MOVE.B ,Abs.W OP_DEF(move_b_ea_absw) { - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_absw); uint32 data = fea_all_1(); - uint32 ea = cea_absw(); + uint32 ea = internal_ea_absw(); ACC.move_8(data); write_1(ea, data); } @@ -1177,9 +1186,10 @@ OP_DEF(move_b_ea_absw) // %0001_001111_mmmrrr d.m+-rxwpi 034 MOVE.B ,Abs.L OP_DEF(move_b_ea_absl) { - CYCLE2(6, 7); + // dst 分込み。 + CYCLE3(move_ea_absl); uint32 data = fea_all_1(); - uint32 ea = cea_absl(); + uint32 ea = internal_ea_absl(); ACC.move_8(data); write_1(ea, data); } @@ -1187,7 +1197,7 @@ OP_DEF(move_b_ea_absl) // %0010_xxx000_mmmrrr dam+-rxwpi 034 MOVE.L ,Dx OP_DEF(move_l_ea_dn) { - CYCLE(2); + CYCLE3(move_ea_dn); uint32 data = fea_all_4(); ACC.move_32(data); RegDX = data; @@ -1196,7 +1206,7 @@ OP_DEF(move_l_ea_dn) // %0010_xxx001_mmmrrr dam+-rxwpi 034 MOVEA.L ,Ax OP_DEF(movea_l) { - CYCLE(2); + CYCLE3(movea_l); uint32 data = fea_all_4(); RegAX = data; } @@ -1204,10 +1214,10 @@ OP_DEF(movea_l) // %0010_xxx010_mmmrrr dam+-rxwpi 034 MOVE.L ,(Ax) OP_DEF(move_l_ea_anin) { - // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anin); uint32 data = fea_all_4(); - uint32 ea = cea_anin(RegIRX); + uint32 ea = internal_ea_anin(RegIRX); ACC.move_32(data); write_4(ea, data); } @@ -1215,12 +1225,12 @@ OP_DEF(move_l_ea_anin) // %0010_xxx011_mmmrrr dam+-rxwpi 034 MOVE.L ,(Ax)+ OP_DEF(move_l_ea_anpi) { - // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anpi); uint32 data = fea_all_4(); // (An)+,(Ax)+ が n==x なら2回目はセーブしてはいけない。 save_reg_pi_if(RegIRX); - uint32 ea = cea_anpi_4(RegIRX); + uint32 ea = internal_ea_anpi_4(RegIRX); ACC.move_32(data); write_4(ea, data); } @@ -1228,12 +1238,12 @@ OP_DEF(move_l_ea_anpi) // %0010_xxx100_mmmrrr dam+-rxwpi 034 MOVE.L ,-(Ax) OP_DEF(move_l_ea_anpd) { - // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anpd); uint32 data = fea_all_4(); // -(An),-(Ax) が n==x なら2回目はセーブしてはいけない。 save_reg_pd_if(RegIRX); - uint32 ea = cea_anpd_4(RegIRX); + uint32 ea = internal_ea_anpd_4(RegIRX); ACC.move_32(data); write_4(ea, data); } @@ -1241,9 +1251,10 @@ OP_DEF(move_l_ea_anpd) // %0010_xxx101_mmmrrr dam+-rxwpi 034 MOVE.L ,d16(Ax) OP_DEF(move_l_ea_andi) { - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_andi); uint32 data = fea_all_4(); - uint32 ea = cea_andi(RegIRX); + uint32 ea = internal_ea_andi(RegIRX); ACC.move_32(data); write_4(ea, data); } @@ -1251,10 +1262,10 @@ OP_DEF(move_l_ea_andi) // %0010_xxx110_mmmrrr dam+-rxwpi 034 MOVE.L ,(Ax,IX) OP_DEF(move_l_ea_anix) { - // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) - CYCLE2(16, 18); + // dst 分込み。 + CYCLE3(move_ea_anix); uint32 data = fea_all_4(); - uint32 ea = cea_anix(RegIRX); + uint32 ea = internal_ea_anix(RegIRX); ACC.move_32(data); write_4(ea, data); } @@ -1262,9 +1273,10 @@ OP_DEF(move_l_ea_anix) // %0010_000111_mmmrrr dam+-rxwpi 034 MOVE.L ,Abs.W OP_DEF(move_l_ea_absw) { - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_absw); uint32 data = fea_all_4(); - uint32 ea = cea_absw(); + uint32 ea = internal_ea_absw(); ACC.move_32(data); write_4(ea, data); } @@ -1272,9 +1284,10 @@ OP_DEF(move_l_ea_absw) // %0010_001111_mmmrrr dam+-rxwpi 034 MOVE.L ,Abs.L OP_DEF(move_l_ea_absl) { - CYCLE2(6, 7); + // dst 分込み。 + CYCLE3(move_ea_absl); uint32 data = fea_all_4(); - uint32 ea = cea_absl(); + uint32 ea = internal_ea_absl(); ACC.move_32(data); write_4(ea, data); } @@ -1282,7 +1295,7 @@ OP_DEF(move_l_ea_absl) // %0011_xxx000_mmmrrr dam+-rxwpi 034 MOVE.W ,Dx OP_DEF(move_w_ea_dn) { - CYCLE(2); + CYCLE3(move_ea_dn); uint32 data = fea_all_2(); ACC.move_16(data); RegDX = (RegDX & 0xffff0000) | data; @@ -1291,7 +1304,7 @@ OP_DEF(move_w_ea_dn) // %0011_xxx001_mmmrrr dam+-rxwpi 034 MOVEA.W ,Ax OP_DEF(movea_w) { - CYCLE(2); + CYCLE3(movea_w); uint32 data = (int32)(int16)fea_all_2(); RegAX = data; } @@ -1299,10 +1312,10 @@ OP_DEF(movea_w) // %0011_xxx010_mmmrrr dam+-rxwpi 034 MOVE.W ,(Ax) OP_DEF(move_w_ea_anin) { - // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anin); uint32 data = fea_all_2(); - uint32 ea = cea_anin(RegIRX); + uint32 ea = internal_ea_anin(RegIRX); ACC.move_16(data); write_2(ea, data); } @@ -1310,12 +1323,12 @@ OP_DEF(move_w_ea_anin) // %0011_xxx011_mmmrrr dam+-rxwpi 034 MOVE.W ,(Ax)+ OP_DEF(move_w_ea_anpi) { - // 実際にはソースがレジスタなら (3, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anpi); uint32 data = fea_all_2(); // (An)+,(Ax)+ が n==x なら2回目はセーブしてはいけない。 save_reg_pi_if(RegIRX); - uint32 ea = cea_anpi_2(RegIRX); + uint32 ea = internal_ea_anpi_2(RegIRX); ACC.move_16(data); write_2(ea, data); } @@ -1323,12 +1336,12 @@ OP_DEF(move_w_ea_anpi) // %0011_xxx100_mmmrrr dam+-rxwpi 034 MOVE.W ,-(Ax) OP_DEF(move_w_ea_anpd) { - // 実際にはソースがレジスタなら (4, 4)、メモリなら (4, 5) - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_anpd); uint32 data = fea_all_2(); // -(An),-(Ax) が n==x なら2回目はセーブしてはいけない。 save_reg_pd_if(RegIRX); - uint32 ea = cea_anpd_2(RegIRX); + uint32 ea = internal_ea_anpd_2(RegIRX); ACC.move_16(data); write_2(ea, data); } @@ -1336,9 +1349,10 @@ OP_DEF(move_w_ea_anpd) // %0011_xxx101_mmmrrr dam+-rxwpi 034 MOVE.W ,d16(Ax) OP_DEF(move_w_ea_andi) { - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_andi); uint32 data = fea_all_2(); - uint32 ea = cea_andi(RegIRX); + uint32 ea = internal_ea_andi(RegIRX); ACC.move_16(data); write_2(ea, data); } @@ -1346,10 +1360,10 @@ OP_DEF(move_w_ea_andi) // %0011_xxx110_mmmrrr dam+-rxwpi 034 MOVE.W ,(Ax,IX) OP_DEF(move_w_ea_anix) { - // XXX 実際にはdstのフォーマットによって(8,9)-(20,23) - CYCLE2(16, 18); + // dst 分込み。 + CYCLE3(move_ea_anix); uint32 data = fea_all_2(); - uint32 ea = cea_anix(RegIRX); + uint32 ea = internal_ea_anix(RegIRX); ACC.move_16(data); write_2(ea, data); } @@ -1357,9 +1371,10 @@ OP_DEF(move_w_ea_anix) // %0011_000111_mmmrrr dam+-rxwpi 034 MOVE.W ,Abs.W OP_DEF(move_w_ea_absw) { - CYCLE2(4, 5); + // dst 分込み。 + CYCLE3(move_ea_absw); uint32 data = fea_all_2(); - uint32 ea = cea_absw(); + uint32 ea = internal_ea_absw(); ACC.move_16(data); write_2(ea, data); } @@ -1367,9 +1382,10 @@ OP_DEF(move_w_ea_absw) // %0011_001111_mmmrrr dam+-rxwpi 034 MOVE.W ,Abs.L OP_DEF(move_w_ea_absl) { - CYCLE2(6, 7); + // dst 分込み。 + CYCLE3(move_ea_absl); uint32 data = fea_all_2(); - uint32 ea = cea_absl(); + uint32 ea = internal_ea_absl(); ACC.move_16(data); write_2(ea, data); } @@ -1381,7 +1397,7 @@ OP_DEF(negx_b) if (n < 8) { // NEGX.B Dn - CYCLE(2); + CYCLE3(negx_dn); uint32 data = reg.D[n] & 0xff; data = ACC.subx_8(data, 0); reg.D[n] = (reg.D[n] & 0xffffff00) | data; @@ -1389,7 +1405,7 @@ OP_DEF(negx_b) op_illegal(); } else { // NEGX.B - CYCLE2(3, 4); + CYCLE3(negx_ea); uint32 ea = cea_data_1(); uint32 data = read_1(ea); data = ACC.subx_8(data, 0); @@ -1404,7 +1420,7 @@ OP_DEF(negx_w) if (n < 8) { // NEGX.W Dn - CYCLE(2); + CYCLE3(negx_dn); uint32 data = reg.D[n] & 0xffff; data = ACC.subx_16(data, 0); reg.D[n] = (reg.D[n] & 0xffff0000) | data; @@ -1412,7 +1428,7 @@ OP_DEF(negx_w) op_illegal(); } else { // NEGX.W - CYCLE2(3, 4); + CYCLE3(negx_ea); uint32 ea = cea_data_2(); uint32 data = read_2(ea); data = ACC.subx_16(data, 0); @@ -1427,13 +1443,13 @@ OP_DEF(negx_l) if (n < 8) { // NEGX.L Dn - CYCLE(2); + CYCLE3(negx_dn); reg.D[n] = ACC.subx_32(reg.D[n], 0); } else if (n < 16) { op_illegal(); } else { // NEGX.L - CYCLE2(3, 4); + CYCLE3(negx_ea); uint32 ea = cea_data_4(); uint32 data = read_4(ea); data = ACC.subx_32(data, 0); @@ -1449,11 +1465,11 @@ OP_DEF(move_sr_ea) uint n = ir & 0x3f; if (n < 8) { // MOVE.W SR,Dn - CYCLE(4); + CYCLE3(move_sr_dn); reg.D[n] = (reg.D[n] & 0xffff0000) | GetSR(); } else { // MOVE.W SR, - CYCLE2(4, 5); + CYCLE3(move_sr_ea); uint32 ea = cea_data_2(); write_2(ea, GetSR()); } @@ -1467,19 +1483,19 @@ OP_DEF(chk_l) if (CCR.IsN()) { // これは最大値で次の条件式が成立した時の値なので、 // 実際にはこれより小さい確定した値のはずだけど。 - CYCLE2(28, 30); + CYCLE3(chk_excep_max); Exception(M68K::EXCEP_CHK); return; } // 本当はこうじゃないけど、とりあえず uint32 src = fea_data_4(); if ((int32)dst > (int32)src) { - CYCLE2(28, 30); + CYCLE3(chk_excep_max); CCR.SetN(false); Exception(M68K::EXCEP_CHK); return; } - CYCLE(8); + CYCLE3(chk); } // %0100_xxx110_mmmrrr d.m+-rxwpi 034 CHK.W ,Dx @@ -1490,19 +1506,19 @@ OP_DEF(chk_w) if (CCR.IsN()) { // これは最大値で次の条件式が成立した時の値なので、 // 実際にはこれより小さい確定した値のはずだけど。 - CYCLE2(28, 30); + CYCLE3(chk_excep_max); Exception(M68K::EXCEP_CHK); return; } // 本当はこうじゃないけど、とりあえず uint32 src = fea_data_2(); if ((int16)dst > (int16)src) { - CYCLE2(28, 30); + CYCLE3(chk_excep_max); CCR.SetN(false); Exception(M68K::EXCEP_CHK); return; } - CYCLE(8); + CYCLE3(chk); } // %0100_xxx111_mmmrrr ..m..rxwp. 034 LEA.L ,Ax @@ -1513,12 +1529,12 @@ OP_DEF(lea) if (n < 8) { // EXTB.L Dy - CYCLE(4); + CYCLE3(extb); RegDY = (int32)(int8)(RegDY & 0xff); ACC.move_32(RegDY); } else { // LEA.L ,Ax - CYCLE(2); + CYCLE3(lea); RegAX = cea_ctrl(); } } @@ -1530,12 +1546,12 @@ OP_DEF(clr_b) if (n < 8) { // CLR.B Dn - CYCLE(2); + CYCLE3(clr_dn); RegDY &= 0xffffff00; ACC.move_8(0); } else { // CLR.B - CYCLE2(3, 4); + CYCLE3(clr_ea); uint32 ea = cea_data_1(); ACC.move_8(0); write_1(ea, 0); @@ -1549,12 +1565,12 @@ OP_DEF(clr_w) if (n < 8) { // CLR.W Dn - CYCLE(2); + CYCLE3(clr_dn); RegDY &= 0xffff0000; ACC.move_16(0); } else { // CLR.W - CYCLE2(3, 4); + CYCLE3(clr_ea); uint32 ea = cea_data_2(); ACC.move_16(0); write_2(ea, 0); @@ -1568,12 +1584,12 @@ OP_DEF(clr_l) if (n < 8) { // CLR.L Dn - CYCLE(2); + CYCLE3(clr_dn); RegDY = 0; ACC.move_32(0); } else { // CLR.L - CYCLE2(3, 4); + CYCLE3(clr_ea); uint32 ea = cea_data_4(); ACC.move_32(0); write_4(ea, 0); @@ -1588,14 +1604,14 @@ OP_DEF(move_ccr_ea) // 転送は16ビットで行われ、上位バイトと未実装ビットは %0 になる。 if (n < 8) { // MOVE.W CCR,Dn - CYCLE(4); + CYCLE3(move_ccr_dn); reg.D[n] = (reg.D[n] & 0xffff0000) | CCR.Get(); } else if (n < 16) { // MOVE.W CCR,An はない op_illegal(); } else { // MOVE.W CCR, - CYCLE2(4, 5); + CYCLE3(move_ccr_ea); uint32 ea = cea_data_2(); write_2(ea, CCR.Get()); } @@ -1608,12 +1624,12 @@ OP_DEF(neg_b) if (n < 8) { // NEG.B Dn - CYCLE(2); + CYCLE3(neg_dn); uint32 data = ACC.sub_8(reg.D[n] & 0xff, 0); reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // NEG.B - CYCLE2(3, 4); + CYCLE3(neg_ea); uint32 ea = cea_data_1(); uint32 data = read_1(ea); data = ACC.sub_8(data, 0); @@ -1628,12 +1644,12 @@ OP_DEF(neg_w) if (n < 8) { // NEG.W Dn - CYCLE(2); + CYCLE3(neg_dn); uint32 data = ACC.sub_16(reg.D[n] & 0xffff, 0); reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else { // NEG.W - CYCLE2(3, 4); + CYCLE3(neg_ea); uint32 ea = cea_data_2(); uint32 data = read_2(ea); data = ACC.sub_16(data, 0); @@ -1648,11 +1664,11 @@ OP_DEF(neg_l) if (n < 8) { // NEG.L Dn - CYCLE(2); + CYCLE3(neg_dn); reg.D[n] = ACC.sub_32(reg.D[n], 0); } else { // NEG.L - CYCLE2(3, 4); + CYCLE3(neg_ea); uint32 ea = cea_data_4(); uint32 data = read_4(ea); data = ACC.sub_32(data, 0); @@ -1667,7 +1683,7 @@ OP_DEF(move_ea_ccr) if (n < 8) { // MOVE.W Dn,CCR - CYCLE(4); + CYCLE3(move_dn_ccr); uint32 data = reg.D[n] & 0xff; CCR.Set(data); } else if (n < 16) { @@ -1675,7 +1691,7 @@ OP_DEF(move_ea_ccr) op_illegal(); } else { // MOVE.W ,CCR - CYCLE(4); + CYCLE3(move_ea_ccr); uint32 data = fea_data_2(); CCR.Set(data); } @@ -1688,13 +1704,13 @@ OP_DEF(not_b) if (n < 8) { // NOT.B Dn - CYCLE(2); + CYCLE3(not_dn); uint32 data = (~reg.D[n]) & 0xff; ACC.move_8(data); reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // NOT.B - CYCLE2(3, 4); + CYCLE3(not_ea); uint32 ea = cea_data_1(); uint32 data = read_1(ea); data = (~data) & 0xff; @@ -1710,13 +1726,13 @@ OP_DEF(not_w) if (n < 8) { // NOT.W Dn - CYCLE(2); + CYCLE3(not_dn); uint32 data = (~reg.D[n]) & 0xffff; ACC.move_16(data); reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else { // NOT.W - CYCLE2(3, 4); + CYCLE3(not_ea); uint32 ea = cea_data_2(); uint32 data = read_2(ea); data = (~data) & 0xffff; @@ -1732,12 +1748,12 @@ OP_DEF(not_l) if (n < 8) { // NOT.L Dn - CYCLE(2); + CYCLE3(not_dn); reg.D[n] = ~reg.D[n]; ACC.move_32(reg.D[n]); } else { // NOT.L - CYCLE2(3, 4); + CYCLE3(not_ea); uint32 ea = cea_data_4(); uint32 data = read_4(ea); data = ~data; @@ -1751,7 +1767,7 @@ OP_DEF(move_ea_sr) { SUPERVISOR_OP; - CYCLE2(8, 10); + CYCLE3(move_ea_sr); uint16 data = fea_data_2(); SetSR(data); } @@ -1775,20 +1791,20 @@ OP_DEF(nbcd) if (n < 8) { // NBCD.B Dn - CYCLE(6); + CYCLE3(nbcd); uint32 dst = RegDY & 0xff; dst = ACC.sbcd_8(dst, 0); RegDY = (RegDY & 0xffffff00) | dst; } else if (n < 16) { // LINK.L An,# - CYCLE2(6, 7); + CYCLE3(link_l); // レジスタやスタックを変更する前にフェッチしないと、 // ページフォルトで再実行できなくなる int32 imm = fetch_4(); ops_link(imm); } else { // NBCD.B - CYCLE(6); + CYCLE3(nbcd); uint32 ea = cea_data_1(); uint32 dst = read_1(ea); dst = ACC.sbcd_8(dst, 0); @@ -1805,18 +1821,18 @@ OP_DEF(pea) if (n < 8) { // SWAP.W Dy - CYCLE(4); + CYCLE3(swap); reg.D[n] = (reg.D[n] << 16) | (reg.D[n] >> 16); ACC.move_32(reg.D[n]); } else if (n < 16) { // BKPT # // ブレークポイント・アクノリッジサイクルに応答するデバイスはないので // 常に不当命令にする。 - CYCLE(9); // ? + CYCLE3(bkpt); // ? op_illegal(); } else { // PEA.L - CYCLE(4); + CYCLE3(pea); uint32 ea = cea_ctrl(); // ページフォルトに備えて保存する save_reg_pd(7); @@ -1895,7 +1911,10 @@ MPU680x0Device::ops_movem_list_ea(int by } } - CYCLE(4 + 2 * regcount); + // 040 では実際は、転送するデータレジスタの数が0なら1個として + // (Dn + An) * 1 を加算なのだが、そこはもう省略。(68040UM.pdf p.10-23) + CYCLE3(movem_list_ea); + CYCLE3(movem_list_ea_n) * regcount; // 副作用上等! } // %0100_100010_mmmrrr ..m.-rxw.. 034 MOVEM.W , @@ -1906,7 +1925,7 @@ OP_DEF(movem_w_mem) if (n < 8) { // EXT.W Dy - CYCLE(4); + CYCLE3(ext); uint16 data = (int16)(int8)(RegDY & 0xff); ACC.move_16(data); RegDY = (RegDY & 0xffff0000) | data; @@ -1924,7 +1943,7 @@ OP_DEF(movem_l_mem) if (n < 8) { // EXT.L Dy - CYCLE(4); + CYCLE3(ext); RegDY = (int32)(int16)(RegDY & 0x0000ffff); ACC.move_32(RegDY); } else { @@ -1936,7 +1955,7 @@ OP_DEF(movem_l_mem) // %0100_101000_mmmrrr dam+-rxwpi -34 TST.B OP_DEF(tst_b) { - CYCLE(2); + CYCLE3(tst); uint32 data = fea_all_1(); ACC.move_8(data); } @@ -1944,7 +1963,7 @@ OP_DEF(tst_b) // %0100_101001_mmmrrr dam+-rxwpi -34 TST.W OP_DEF(tst_w) { - CYCLE(2); + CYCLE3(tst); uint32 data = fea_all_2(); ACC.move_16(data); } @@ -1952,7 +1971,7 @@ OP_DEF(tst_w) // %0100_101010_mmmrrr dam+-rxwpi -34 TST.L OP_DEF(tst_l) { - CYCLE(2); + CYCLE3(tst); uint32 data = fea_all_4(); ACC.move_32(data); } @@ -1966,7 +1985,7 @@ OP_DEF(tas) if (n < 8) { // TAS.B Dn // リード・モディファイ・ライトという概念はない - CYCLE(4); + CYCLE3(tas_dn); uint32 data = reg.D[n]; ACC.move_8(data); reg.D[n] |= 0x80; @@ -1976,7 +1995,7 @@ OP_DEF(tas) } else { // TAS.B // リード・モディファイ・ライトという概念はない - CYCLE(12); + CYCLE3(tas_ea); uint32 ea = cea_data_1(); uint32 data = read_1(ea); ACC.move_8(data); @@ -2000,11 +2019,11 @@ OP_DEF(mul) uint h = ir2 & 7; uint l = (ir2 >> 12) & 7; - CYCLE(44); // XXX これは本当は最大値だけど switch ((ir2 >> 10) & 3) { case 0: { // MULU.L ,Dl + CYCLE3(mulu_l_max); uint32 src = fea_data_4(); uint32 dst = reg.D[l]; reg.D[l] = ACC.mulu_32(src, dst); @@ -2014,6 +2033,7 @@ OP_DEF(mul) case 1: { // MULU.L ,Dh:Dl + CYCLE3(mulu_l_max); uint32 src = fea_data_4(); uint32 dst = reg.D[l]; uint64 res = ACC.mulu_64(src, dst); @@ -2026,6 +2046,7 @@ OP_DEF(mul) case 2: { // MULS.L ,Dl + CYCLE3(muls_l_max); uint32 src = fea_data_4(); uint32 dst = reg.D[l]; reg.D[l] = ACC.muls_32(src, dst); @@ -2035,6 +2056,7 @@ OP_DEF(mul) case 3: { // MULS.L ,Dh:Dl + CYCLE3(muls_l_max); uint32 src = fea_data_4(); uint32 dst = reg.D[l]; uint64 res = ACC.muls_64(src, dst); @@ -2054,7 +2076,7 @@ OP_DEF(mul) void MPU680x0Device::ops_divu_32_32(uint r, uint q) { - CYCLE(78); // XXX これは本当は最大値だけど + CYCLE3(divu_l_max); uint32 src = fea_data_4(); uint32 dst = reg.D[q]; @@ -2086,7 +2108,7 @@ MPU680x0Device::ops_divu_32_32(uint r, u void MPU680x0Device::ops_divu_64_32(uint r, uint q) { - CYCLE(78); // XXX これは本当は最大値だけど + CYCLE3(divu_l_max); uint32 src = fea_data_4(); uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q]; @@ -2129,7 +2151,7 @@ MPU680x0Device::ops_divu_64_32(uint r, u void MPU680x0Device::ops_divs_32_32(uint r, uint q) { - CYCLE(90); // XXX これは本当は最大値だけど + CYCLE3(divs_l_max); uint32 src = fea_data_4(); uint32 dst = reg.D[q]; @@ -2174,7 +2196,7 @@ MPU680x0Device::ops_divs_32_32(uint r, u void MPU680x0Device::ops_divs_64_32(uint r, uint q) { - CYCLE(90); // XXX これは本当は最大値だけど + CYCLE3(divs_l_max); uint32 src = fea_data_4(); uint64 dst = (((uint64)reg.D[r]) << 32) | reg.D[q]; @@ -2335,7 +2357,10 @@ MPU680x0Device::ops_movem_ea_list(int by RegAY = ea; } - CYCLE(8 + 4 * regcount); + // 040 では実際は、転送するデータレジスタの数が0なら1個として + // (Dn + An) * 1 を加算なのだが、そこはもう省略。(68040UM.pdf p.10-23) + CYCLE3(movem_ea_list); + CYCLE3(movem_ea_list_n) * regcount; // 副作用上等! } // %0100_110010_mmmrrr ..m+.rxwp. 034 MOVEM.W , @@ -2375,7 +2400,7 @@ MPU680x0Device::ops_movec_rc_rn() { SUPERVISOR_OP; - CYCLE(6); + CYCLE3(movec_rc_rn); ir2 = fetch_2(); uint n = ir2 >> 12; uint c = ir2 & 0xfff; @@ -2489,27 +2514,27 @@ MPU680x0Device::ops_movec_rn_rc() // なければ共通レジスタを試す。 switch (c) { case 0x000: - CYCLE(12); + CYCLE3(movec_rn_rcb); reg.sfc = busaddr::FC(reg.R[n] & 7) | BusAddr::R; return; case 0x001: - CYCLE(12); + CYCLE3(movec_rn_rcb); reg.dfc = busaddr::FC(reg.R[n] & 7) | BusAddr::W; return; case 0x002: - CYCLE(12); + CYCLE3(movec_rn_rcb); SetCACR(reg.R[n]); return; case 0x800: - CYCLE(6); + CYCLE3(movec_rn_rca); reg.usp = reg.R[n]; return; case 0x801: - CYCLE(6); + CYCLE3(movec_rn_rca); reg.vbr = reg.R[n]; return; case 0x803: - CYCLE(6); + CYCLE3(movec_rn_rca); if (reg.m) { reg.A[7] = reg.R[n]; } else { @@ -2517,7 +2542,7 @@ MPU680x0Device::ops_movec_rn_rc() } return; case 0x804: - CYCLE(6); + CYCLE3(movec_rn_rca); if (reg.m) { reg.isp = reg.R[n]; } else { @@ -2536,7 +2561,7 @@ MPU68030Device::ops_movec_rn_rc_cpu(uint { switch (c) { case 0x802: - CYCLE(6); + CYCLE3(movec_rn_rca); reg.caar = reg.R[n]; return true; default: @@ -2603,13 +2628,13 @@ OP_DEF(trap) switch (n) { case 0x00 ... 0x0e:// TRAP # - CYCLE2(18, 20); + CYCLE3(trap); // TRAP#N 例外 Exception(M68K::EXCEP_TRAP0 + n); return; case 0x0f: // TRAP #15 - CYCLE2(18, 20); + CYCLE3(trap); // TRAP#15 例外 (IOCS コール表示のためこれだけ別処理) ExceptionTrap15(); return; @@ -2623,7 +2648,7 @@ OP_DEF(trap) case 0x16: case 0x17: // LINK.W Ay,# { - CYCLE2(4, 5); + CYCLE3(link_w); // レジスタやスタックを変更する前にフェッチとセーブをしないと、 // ページフォルトで再実行できなくなる int32 imm = (int32)(int16)fetch_2(); @@ -2639,7 +2664,7 @@ OP_DEF(trap) case 0x1d: case 0x1e: case 0x1f: // UNLK Ay - CYCLE(5); + CYCLE3(unlk); // ページフォルトに備えて保存する save_reg_pi(7); reg.A[7] = RegAY; @@ -2655,7 +2680,7 @@ OP_DEF(trap) case 0x26: case 0x27: // MOVE.L Ay,USP SUPERVISOR_OP; - CYCLE(4); + CYCLE3(move_an_usp); reg.usp = RegAY; return; @@ -2668,23 +2693,24 @@ OP_DEF(trap) case 0x2e: case 0x2f: // MOVE.L USP,Ay SUPERVISOR_OP; - CYCLE(4); + CYCLE3(move_usp_an); RegAY = reg.usp; return; case 0x30: // RESET + // CYCLE3() は int8 なので。 CYCLE(518); ops_reset(); return; case 0x31: // NOP - CYCLE(2); + CYCLE3(nop); // XXX ほんとは何かするらしいけど return; case 0x32: // STOP # SUPERVISOR_OP; - CYCLE(8); + CYCLE3(stop); ops_stop(); return; @@ -2695,7 +2721,7 @@ OP_DEF(trap) case 0x34: // RTD # { - CYCLE2(10, 12); + CYCLE3(rtd); // ページフォルトに備えて保存する save_reg_pi(7); uint32 disp = fetch_2(); @@ -2705,7 +2731,7 @@ OP_DEF(trap) } case 0x35: // RTS - CYCLE2(9, 11); + CYCLE3(rts); // ページフォルトに備えて保存する save_reg_pi(7); Jump(pop_4()); @@ -2713,15 +2739,15 @@ OP_DEF(trap) case 0x36: // TRAPV if (CCR.IsV()) { - CYCLE2(22, 24); + CYCLE3(trapv_excep); Exception(M68K::EXCEP_TRAPV); } else { - CYCLE(4); + CYCLE3(trapv); } return; case 0x37: // RTR - CYCLE2(12, 14); + CYCLE3(rtr); // ページフォルトに備えて保存する save_reg_pi(7); CCR.Set(pop_2()); @@ -2745,7 +2771,7 @@ OP_DEF(trap) // %0100_111010_mmmrrr ..m..rxwp. 034 JSR OP_DEF(jsr) { - CYCLE2(4, 7); + CYCLE3(jsr); uint32 ea = cea_ctrl(); uint32 return_addr = reg.pc; @@ -2758,7 +2784,7 @@ OP_DEF(jsr) // %0100_111011_mmmrrr ..m..rxwp. 034 JMP OP_DEF(jmp) { - CYCLE2(4, 6); + CYCLE3(jmp); // 実際には CEA ではなく JEA の実行時間を足すんだがまあいいか uint32 ea = cea_ctrl(); Jump(ea); @@ -2773,12 +2799,12 @@ OP_DEF(addq_b) src = (src == 0) ? 8 : src; if (n < 8) { // ADDQ.B #qqq,Dn - CYCLE(2); + CYCLE3(addq_rn); uint32 data = ACC.add_8(src, reg.D[n] & 0xff); reg.D[n] = (reg.D[n] & 0xffffff00) | data; } else { // ADDQ.B #qqq, - CYCLE2(3, 4); + CYCLE3(addq_ea); uint32 ea = cea_data_1(); uint32 data = read_1(ea); data = ACC.add_8(src, data); @@ -2796,17 +2822,17 @@ OP_DEF(addq_w) src = (src == 0) ? 8 : src; if (n < 8) { // ADDQ.W #qqq,Dn - CYCLE(2); + CYCLE3(addq_rn); uint32 data = ACC.add_16(src, reg.D[n] & 0xffff); reg.D[n] = (reg.D[n] & 0xffff0000) | data; } else if (n < 16) { // ADDQ.W #qqq,An は ADDQ.L と等価 // フラグは変化しない - CYCLE(2); + CYCLE3(addq_rn); reg.R[n] += src; } else { // ADDQ.W #qqq, - CYCLE2(3, 4); + CYCLE3(addq_ea); uint32 ea = cea_data_2(); uint32 data = read_2(ea); data = ACC.add_16(src, data); @@ -2824,16 +2850,16 @@ OP_DEF(addq_l) src = (src == 0) ? 8 : src; if (n < 8) { // ADDQ.L #qqq,Dn - CYCLE(2); + CYCLE3(addq_rn); reg.D[n] = ACC.add_32(src, reg.D[n]); } else if (n < 16) { // ADDQ.L #qqq,An // フラグは変化しない - CYCLE(2); + CYCLE3(addq_rn); reg.R[n] += src; } else { // ADDQ.L #qqq, - CYCLE2(3, 4); + CYCLE3(addq_ea); uint32 ea = cea_data_4(); uint32 data = read_4(ea); data = ACC.add_32(src, data); @@ -2848,11 +2874,11 @@ MPU680x0Device::ops_trapcc(uint cond) // 条件成立すれば例外。成立しなければ何もしない。 // いずれの場合もオペランドありの形態なら事前に読み飛ばしておくこと。 if (CCR.Cond(cond)) { - CYCLE2(22, 24); + CYCLE3(trapcc_excep); Exception(M68K::EXCEP_TRAPV); } else { // サイクルを消費するだけ - CYCLE(4); + CYCLE3(trapcc); } } @@ -2869,7 +2895,7 @@ OP_DEF(scc) switch (n) { case 0b000000 ... 0b000111: // Scc.B Dn - CYCLE(4); + CYCLE3(scc_dn); if (CCR.Cond(cond)) { RegDY |= 0xff; } else { @@ -2880,7 +2906,7 @@ OP_DEF(scc) case 0b001000 ... 0b001111: // DBcc.W Dy,