--- nono/m680x0/m68030subr.cpp 2026/04/29 17:04:46 1.1.1.6 +++ nono/m680x0/m68030subr.cpp 2026/04/29 17:04:49 1.1.1.7 @@ -8,6 +8,7 @@ #include "m68030bus.h" #include "m68030fpu.h" #include "debugger.h" +#include "scheduler.h" static void m68030_change_intr(m68kcpu *, int); static void m68030_set_intr(m68kcpu *, int); @@ -43,6 +44,31 @@ m68030_get_vtime(m68kcpu *cpu) return cpu->total_vtime + cpu->Cycle2Vtime(cpu->used_cycle); } +// クロックを設定する。 +void +m68030_set_clockspeed(m68kcpu *cpu, uint32 clock_khz_) +{ + cpu->clock_khz = clock_khz_; + + // サイクル数を nsec に変換する際の係数。25MHz なら c2v は 40 [nsec/clock] + cpu->c2v = 1000 * 1000 / cpu->clock_khz; + + // nsec をクロック数に変換する際の係数、つまり c2v の逆数。 + // (http://hp.vector.co.jp/authors/VA003988/how_to_o.htm#27_2) + int b = 32 - __builtin_clz(cpu->c2v) - 1; + int r = 32 + b; + // 小数部を近接丸め(0捨1入)するため一桁余分に計算しておいて.. + uint64 f = (1ULL << (r + 1)) / cpu->c2v; + // 最下位ビットを丸める + if ((f & 1) != 0) { + f += 1; + } + f >>= 1; + + cpu->v2c_factor = f; + cpu->v2c_shift = r; +} + // 二重バスフォールト static void m68030_double_bus_fault(m68kcpu *cpu, const char *where) @@ -85,9 +111,11 @@ m68030_exception_reset(m68kcpu *cpu) // 2. S をセット、M をクリア // 3. 割り込みレベルを 7 - // 受け付け中だった割り込みをクリア + // 受け付け中だった割り込みをクリア。 + // STOP 状態とホールト状態を解除。 cpu->intr_pending = 0; - cpu->atomic_reqflag &= ~CPU_REQ_INTR; + cpu->atomic_reqflag &= ~(CPU_REQ_INTR | CPU_REQ_STOP | CPU_REQ_HALT); + cpu->reg.state = Scheduler::SCHED_CPU_NORMAL; // ここは set_sr を使わずに設定する。 cpu->reg.s = true;