--- nono/m680x0/m680x0ea.cpp 2026/04/29 17:05:30 1.1 +++ nono/m680x0/m680x0ea.cpp 2026/04/29 17:05:40 1.1.1.2 @@ -106,6 +106,7 @@ // | m+ rxwp | FRESTORE #include "mpu680x0.h" +#include "m680x0cycle.h" // // Calc EA @@ -118,91 +119,91 @@ uint32 MPU680x0Device::cea_anin(uint n) { - CYCLE(2); + CYCLE3(cea_anin); return internal_ea_anin(n); } uint32 MPU680x0Device::cea_anpi_1(uint n) { - CYCLE(2); + CYCLE3(cea_anpi); return internal_ea_anpi_1(n); } uint32 MPU680x0Device::cea_anpi_2(uint n) { - CYCLE(2); + CYCLE3(cea_anpi); return internal_ea_anpi_2(n); } uint32 MPU680x0Device::cea_anpi_4(uint n) { - CYCLE(2); + CYCLE3(cea_anpi); return internal_ea_anpi_4(n); } uint32 MPU680x0Device::cea_anpd_1(uint n) { - CYCLE(2); + CYCLE3(cea_anpd); return internal_ea_anpd_1(n); } uint32 MPU680x0Device::cea_anpd_2(uint n) { - CYCLE(2); + CYCLE3(cea_anpd); return internal_ea_anpd_2(n); } uint32 MPU680x0Device::cea_anpd_4(uint n) { - CYCLE(2); + CYCLE3(cea_anpd); return internal_ea_anpd_4(n); } uint32 MPU680x0Device::cea_andi(uint n) { - CYCLE(2); + CYCLE3(cea_andi); return internal_ea_andi(n); } uint32 MPU680x0Device::cea_anix(uint n) { - CYCLE(10); // XXX 4,4-18,20 + // CYCLE は呼び出し先で加算。 return internal_ea_anix(n); } uint32 MPU680x0Device::cea_absw() { - CYCLE(2); + CYCLE3(cea_absw); return internal_ea_absw(); } uint32 MPU680x0Device::cea_absl() { - CYCLE(4); + CYCLE3(cea_absl); return internal_ea_absl(); } uint32 MPU680x0Device::cea_pcdi() { - CYCLE(2); + CYCLE3(cea_andi); return internal_ea_pcdi(); } uint32 MPU680x0Device::cea_pcix() { - CYCLE(10); // XXX 4,4-18,20 + // CYCLE は呼び出し先で加算。 return internal_ea_pcix(); } @@ -213,110 +214,149 @@ MPU680x0Device::cea_pcix() inline uint32 MPU680x0Device::fea_anin() { - CYCLE(3); + CYCLE3(fea_anin); return internal_ea_anin(eanum(ir)); } inline uint32 MPU680x0Device::fea_anpi_1() { - CYCLE(3); + CYCLE3(fea_anpi); return internal_ea_anpi_1(eanum(ir)); } inline uint32 MPU680x0Device::fea_anpi_2() { - CYCLE(3); + CYCLE3(fea_anpi); return internal_ea_anpi_2(eanum(ir)); } inline uint32 MPU680x0Device::fea_anpi_4() { - CYCLE(3); + CYCLE3(fea_anpi); return internal_ea_anpi_4(eanum(ir)); } inline uint32 MPU680x0Device::fea_anpd_1() { - CYCLE(4); + CYCLE3(fea_anpd); return internal_ea_anpd_1(eanum(ir)); } inline uint32 MPU680x0Device::fea_anpd_2() { - CYCLE(4); + CYCLE3(fea_anpd); return internal_ea_anpd_2(eanum(ir)); } inline uint32 MPU680x0Device::fea_anpd_4() { - CYCLE(4); + CYCLE3(fea_anpd); return internal_ea_anpd_4(eanum(ir)); } inline uint32 MPU680x0Device::fea_andi() { - CYCLE(4); + CYCLE3(fea_andi); return internal_ea_andi(eanum(ir)); } inline uint32 MPU680x0Device::fea_anix() { - CYCLE2(12, 14); // XXX 6,6-18,21 + // CYCLE は呼び出し先で加算。 return internal_ea_anix(eanum(ir)); } inline uint32 MPU680x0Device::fea_absw() { - CYCLE(4); + CYCLE3(fea_absw); return internal_ea_absw(); } inline uint32 MPU680x0Device::fea_absl() { - CYCLE2(4, 5); + CYCLE3(fea_absl); return internal_ea_absl(); } inline uint32 MPU680x0Device::fea_pcdi() { - CYCLE(4); + CYCLE3(fea_andi); return internal_ea_pcdi(); } inline uint32 MPU680x0Device::fea_pcix() { - CYCLE2(12, 14); // XXX 6,6-18,21 + // CYCLE は呼び出し先で加算。 return internal_ea_pcix(); } inline void MPU680x0Device::fea_imm_2() { - CYCLE(2); + CYCLE3(fea_immw); } inline void MPU680x0Device::fea_imm_4() { - CYCLE(4); + CYCLE3(fea_imml); } // // EA の拡張ワード // +// 所要サイクルについて。 +// 本来 internal_ea_*() はサイクルを加算しないが、ea_ix は展開してみないと +// 分からないのでここで加算する。CEA と FEA の両方から呼ばれて本来なら +// サイクル数が異なるのだが、実際にサイクル数が異なるのは No Cache Case 側 +// だけなので、簡略化のため FEA (の NCC) のことは忘れる。 +// +// サイクルは、メモリ間接かどうか、ベースディスプレースメント(bd) のサイズ、 +// アウターディスプレースメント(od) のサイズ、の3つのパラメータで決まる。 +// +// 間接 bd od CEA bd加算分 od加算分 +// ---- ---- ---- ---- +// n - - (6,6) +// n 16 - (8,9) = (6,6) + (2,3) +// n 32 - (12,12) = (6,6) + (6,6) +// y - - (10,10) +// y - 16/32 (12,13) = (10,10) + (2,3) +// y 16 - (12,13) = (10,10) + (2,3) +// y 16 16/32 (14,16) = (10,10) + (2,3) + (2,3) +// y 32 - (16,17) = (10,10) + (6,7)※1 +// y 32 16/32 (18,20) = (10,10) + (6,7)※1+ (2,3) +// +// ※1: 簡略化のためここの (6,7) は (6,6) として扱う。 +// +// FEA はだいたいこんな感じになるが、実装はしない。 +// +// 間接 bd od FEA bd加算分 od加算分 +// ---- ---- ---- ---- +// n - - (6,7) +// n 16 - (8,10) = (6,7) + (2,3) +// n 32 - (12,13) = (6,7) + (6,6) +// y - - (10,10) +// y - 16 (12,13) = (10,10) + (2,3) +// y - 32 (12,14) = (10,10) + (2,4) +// y 16 - (12,13) +// y 16 16 (14,16) = (10,10) + (2,3) + (2,3) +// y 16 32 (14,17) = (10,10) + (2,3) + (2,4) +// y 32 - (16,17) = (10,10) + (6,7) +// y 32 16 (18,20) = (10,10) + (6,7) + (2,3) +// y 32 32 (18,21) = (10,10) + (6,7) + (2,4) uint32 MPU680x0Device::internal_ea_ix(uint32 anpc) { @@ -336,7 +376,7 @@ MPU680x0Device::internal_ea_ix(uint32 an // WL: インデックスレジスタ(Rn)のサイズ 1=.L 0=.W // SCALE: スケールファクタ %00=*1 %01=*2 %10=*4 %11=*8 - CYCLE(4); + CYCLE3(cea_anix_brief); int32 disp = (int32)(int8)(ext & 0xff); uint32 idx; @@ -360,16 +400,6 @@ MPU680x0Device::internal_ea_ix(uint32 an // BDSZ: ベースディスプレースメントのサイズ %01=null %10=.W %11=.L // I/IS: モード - // クロックは概略値なので完全に正確ではないがまず基本は以下の2通り。 - // メモリ間接なし (6, 6) - // メモリ間接あり (10, 10) - // これを元に必要に応じて以下をそれぞれ加算する。 - // bd16 (+2, +3) - // bd32 (メモリ間接なし) (+4, +6) - // bd32 (メモリ間接あり) (+6, +6) - // outer (W/L 不問) (+2, +3) - // ただしここでは実行順の都合で bd32 はいずれも (+4, +6) とした。 - bool bs = (ext & 0x0080); bool is = (ext & 0x0040); uint bdsize = (ext >> 4) & 3; @@ -389,11 +419,11 @@ MPU680x0Device::internal_ea_ix(uint32 an break; case 2: // ベース.W base = (int32)(int16)fetch_2(); - CYCLE2(2, 3); + CYCLE3(cea_anix_bd2); break; case 3: // ベース.L base = fetch_4(); - CYCLE2(4, 6); + CYCLE3(cea_anix_bd4); break; default: __unreachable(); @@ -412,18 +442,18 @@ MPU680x0Device::internal_ea_ix(uint32 an switch (iis) { case 0: // no memory indirection - CYCLE(6); + CYCLE3(cea_anix_direct); return anpc + base + idx; case 1: // indirect pre-index with null outer - CYCLE(10); + CYCLE3(cea_anix_indir); return read_4(anpc + base + idx); case 2: // indirect pre-index with word outer - CYCLE2(10+2, 10+3); + CYCLE3(cea_anix_indir_od); outer = (int32)(int16)fetch_2(); return read_4(anpc + base + idx) + outer; case 3: // indirect pre-index with long outer - CYCLE2(10+2, 10+3); + CYCLE3(cea_anix_indir_od); outer = fetch_4(); return read_4(anpc + base + idx) + outer; @@ -431,14 +461,14 @@ MPU680x0Device::internal_ea_ix(uint32 an throw M68K::EXCEP_ILLEGAL; case 5: // indirect post-index with null outer - CYCLE(10); + CYCLE3(cea_anix_indir); return read_4(anpc + base) + idx; case 6: // indirect post-index with word outer - CYCLE2(10+2, 10+3); + CYCLE3(cea_anix_indir_od); outer = (int32)(int16)fetch_2(); return read_4(anpc + base) + idx + outer; case 7: // indirect post-index with long outer - CYCLE2(10+2, 10+3); + CYCLE3(cea_anix_indir_od); outer = fetch_4(); return read_4(anpc + base) + idx + outer; default: @@ -447,18 +477,18 @@ MPU680x0Device::internal_ea_ix(uint32 an } else { switch (iis) { case 0: // no memory indirection - CYCLE(6); + CYCLE3(cea_anix_direct); return anpc + base; case 1: // memory indirect with null outer - CYCLE(10); + CYCLE3(cea_anix_indir); return read_4(anpc + base); case 2: // memory indirect with word outer - CYCLE2(10+2, 10+3); + CYCLE3(cea_anix_indir_od); outer = (int32)(int16)fetch_2(); return read_4(anpc + base) + outer; case 3: // memory indirect with long outer - CYCLE2(10+2, 10+3); + CYCLE3(cea_anix_indir_od); outer = fetch_4(); return read_4(anpc + base) + outer; default: