--- nono/vm/sysctlr.cpp 2026/04/29 17:05:07 1.1.1.7 +++ nono/vm/sysctlr.cpp 2026/04/29 17:05:14 1.1.1.9 @@ -4,15 +4,24 @@ // Licensed under nono-license.txt // +// // LUNA88K のシステムコントローラのような何か +// -#include "sysctlr.h" -#include "ethernet.h" -#include "mpu88xx0.h" -#include "prom.h" -#include "sio.h" -#include "spc.h" -#include "sysclk.h" +// IODevice +// | +// +-- InterruptDevice (割り込みコントローラの共通部) +// | +// +-- M680x0Interrupt (m68k 割り込みコントローラの共通部) +// | | +// | +-- X68030Interrupt (X68030 の割り込みコントローラ) +// | +-- LunaInterrupt (LUNA-I の割り込みコントローラ) +// | +// +-- PEDECDevice (X68030 の Lv1 担当コントローラ) +// | +// | +---------------+ +// +--| SysCtlrDevice | (LUNA88K の割り込みコントローラ) +// +---------------+ // この辺を全部一つのデバイスで受け付けておくか。BusIO はまた後で考える。 // $6500000n.b HW 割り込みレベル (n*4 = CPU#n) @@ -144,6 +153,14 @@ // リードアクセスで読み込まれる値も不定のようだ。 // 要はアドレスバスとR/W信号線しか見ていない。 +#include "sysctlr.h" +#include "ethernet.h" +#include "mpu88xx0.h" +#include "nmi.h" +#include "prom.h" +#include "sio.h" +#include "spc.h" +#include "sysclk.h" // コンストラクタ SysCtlrDevice::SysCtlrDevice() @@ -151,7 +168,7 @@ SysCtlrDevice::SysCtlrDevice() { AddAlias("SysCtlr"); - monitor.func = (MonitorCallback_t)&SysCtlrDevice::MonitorUpdate; + monitor.func = ToMonitorCallback(&SysCtlrDevice::MonitorUpdate); monitor.SetSize(25, 10); monitor.Regist(ID_MONITOR_INTERRUPT); } @@ -161,11 +178,12 @@ SysCtlrDevice::~SysCtlrDevice() { } +// リセット void -SysCtlrDevice::ResetHard() +SysCtlrDevice::ResetHard(bool poweron) { // さすがにリセットくらいはされるだろう… - inherited::ResetHard(); + inherited::ResetHard(poweron); for (int i = 0; i < 4; i++) { // XXX 初期値は分からないがとりあえず割り込み禁止にしておく @@ -197,15 +215,15 @@ SysCtlrDevice::Read32(uint32 addr) } if (0x6d000000 <= addr && addr < 0x6d000010) { - putlog(0, "CPU%d リセット 未実装読み込み", n); + putlog(0, "Read CPU%d reset (NOT IMPLEMENTED)", n); return 0xffffffff; } if (addr == 0x6d000010) { - putlog(0, "CPU ALL リセット 未実装読み込み"); + putlog(0, "Read All CPU reset (NOT IMPLEMENTED)"); return 0xffffffff; } - putlog(0, "未実装読み込み $%08x", addr); + putlog(0, "Read $%08x (NOT IMPLEMENTED)", addr); return 0xffffffff; } @@ -219,9 +237,9 @@ SysCtlrDevice::Write32(uint32 addr, uint // 割り込みレベル変えるたびに表示されるのですごく多い。 // さらに同レベルが書き込まれることも多い…。 if (cpu[n].maskval != data) { - putlog(2, "割り込みマスク(CPU#%d) <- $%08x", n, data); + putlog(2, "Interrupt Mask(CPU#%d) <- $%08x", n, data); } else { - putlog(3, "割り込みマスク(CPU#%d) <- $%08x", n, data); + putlog(3, "Interrupt Mask(CPU#%d) <- $%08x", n, data); } // 設定値を保存 @@ -240,18 +258,23 @@ SysCtlrDevice::Write32(uint32 addr, uint return 0; } if (0x6d000000 <= addr && addr < 0x6d000010) { - putlog(0, "CPU%d リセット 未実装書き込み", n); + putlog(0, "Write CPU%d reset (NOT IMPLEMENTED)", n); return 0; } if (addr == 0x6d000010) { putlog(1, "Reset All CPUs"); - gPROM0->ResetHard(); - gMPU->ResetHard(); - gMPU->Release(); + // XXX このあたりもう少し整理する必要がある + // 今は MPU.ResetHard() が func を ResetCallback に、time をリセット + // 間隔に書き換えて Start() した後、この書き込み命令から戻ったところの + // ExecCallback が time だけ所要サイクルに書き換えて再度 Start() する + // ため、時間はともかく幸い ResetCallback() が呼ばれることで動いている。 + gPROM0->ResetHard(false); + gMPU->ResetHard(false); + ResetHard(false); return 0; } - putlog(0, "未実装書き込み $%08x <- $%08x", addr, data); + putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", addr, data); return 0; } @@ -339,18 +362,21 @@ SysCtlrDevice::MonitorUpdate(Monitor *, uint32 SysCtlrDevice::GetIntmap(Device *source) const { - if (__predict_true(source == gSysClk.get())) { + if (__predict_true(source == gSysClk)) { return IntmapSysClk; } - if (__predict_true(source == gSIO.get())) { + if (__predict_true(source == gSIO)) { return IntmapSIO; } - if (__predict_true(source == gEthernet.get())) { + if (__predict_true(source == gEthernet)) { return IntmapLance; } - if (__predict_true(source == gSPC.get())) { + if (__predict_true(source == gSPC)) { return IntmapSPC; } + if (source == gNMI) { + return IntmapNMI; + } PANIC("Unknown interrupt source?"); } @@ -403,4 +429,3 @@ SysCtlrDevice::MakeIntMask(uint32 data, return val; } -