--- nono/m88xx0/m88100subr.cpp 2026/04/29 17:04:44 1.1.1.5 +++ nono/m88xx0/m88100subr.cpp 2026/04/29 17:04:49 1.1.1.6 @@ -13,6 +13,31 @@ m88kcpu::m88kcpu(uint32 reset_vector_) cmmu[0].Ctor(this); cmmu[1].Ctor(this); + + // レジスタのうち不定と明記されてるものは、未初期化のまま触ったことが + // 分かりやすいような適当なパターンで埋めておく。ただし最上位も c に + // すると BT454 のレジスタ付近を指してしまうので、それは避けておく。 + // XXX Super Reset が出来たらそっちに移動? + const uint32 Undefined = 0x0ccccccc; + for (int i = 1; i < 32; i++) { + r[i] = Undefined; + } + for (int i = 1; i < 9; i++) { + fcr[i] = Undefined; + } + epsr = Undefined; + ssbr = Undefined; + sfip = Undefined; + snip = Undefined; + sxip = Undefined; + // DMTx は bit0(Valid) をクリア。DMAx/DMDx は不定。 + dma0 = Undefined; + dma1 = Undefined; + dma2 = Undefined; + dmd0 = Undefined; + dmd1 = Undefined; + dmd2 = Undefined; + } // デストラクタ @@ -20,6 +45,31 @@ m88kcpu::~m88kcpu() { } +// MPU クロックを設定 +void +m88kcpu::SetClockSpeed(uint32 clock_khz_) +{ + clock_khz = clock_khz_; + + // サイクル数を nsec に変換する際の係数。25MHz なら c2v は 40 [nsec/clock] + c2v = 1000 * 1000 / clock_khz; + + // nsec をクロック数に変換する際の係数、つまり c2v の逆数。 + // (http://hp.vector.co.jp/authors/VA003988/how_to_o.htm#27_2) + int b = 32 - __builtin_clz(c2v) - 1; + int rr = 32 + b; + // 小数部を近接丸め(0捨1入)するため一桁余分に計算しておいて.. + uint64 f = (1ULL << (rr + 1)) / c2v; + // 最下位ビットを丸める + if ((f & 1) != 0) { + f += 1; + } + f >>= 1; + + v2c_factor = f; + v2c_shift = rr; +} + // PID の VERSION フィールドをセットする。初期化時に呼ぶ。 void m88kcpu::SetVersion(uint32 version)