--- nono/m88xx0/m88100subr.cpp 2026/04/29 17:04:34 1.1.1.2 +++ nono/m88xx0/m88100subr.cpp 2026/04/29 17:04:52 1.1.1.7 @@ -11,6 +11,31 @@ m88kcpu::m88kcpu() { 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; + } // デストラクタ @@ -18,6 +43,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) @@ -48,3 +98,50 @@ m88kcpu::SetVersion(uint32 version) "111-", // not used normally "LLLL", }; + +// 例外 +/*static*/ const char * const m88kcpu::exception_names[] = { + // 01234567890123456789012 <- 例外履歴欄の横幅 + /* 0 */ "Reset Exception", + /* 1 */ "Interrupt Exception", + /* 2 */ "Inst Access Exception", + /* 3 */ "Data Access Exception", + /* 4 */ "Misaligned Access Excep", + /* 5 */ "Unimplemented Opcode", + /* 6 */ "Priv. Violation Excep.", + /* 7 */ "Bounds Check Violation", + /* 8 */ "Illegal Integer Divide", + /* 9 */ "Int Overflow Exception", + /* 10 */ "Error Exception", + // 01234567890123456789012 +}; + +// 例外名を返す。 +// Reserved なところは NULL を返す。 +// XXX TODO 114 以降未実装 +/*static*/ const char * +m88kcpu::GetExceptionName(int vector) +{ + if (0 <= vector && vector < countof(exception_names)) { + return exception_names[vector]; + } + + // OpenBSD + // XXX 本来は OpenBSD 稼働時に限定すべきだろうけど、そうする意味もない + switch (vector) { + case 450: + return "OpenBSD system call"; + case 451: + return "OpenBSD cache flush"; + case 503: + return "Division by zero in GCC"; + case 504: + return "OpenBSD stepbpt"; + case 511: + return "OpenBSD userbpt"; + default: + break; + } + + return NULL; +}