--- nono/vm/sysctlr.cpp 2026/04/29 17:05:10 1.1.1.8 +++ nono/vm/sysctlr.cpp 2026/04/29 17:05:17 1.1.1.10 @@ -5,7 +5,7 @@ // // -// LUNA88K のシステムコントローラのような何か +// LUNA-88K のシステムコントローラのような何か // // IODevice @@ -20,7 +20,7 @@ // +-- PEDECDevice (X68030 の Lv1 担当コントローラ) // | // | +---------------+ -// +--| SysCtlrDevice | (LUNA88K の割り込みコントローラ) +// +--| SysCtlrDevice | (LUNA-88K の割り込みコントローラ) // +---------------+ // この辺を全部一つのデバイスで受け付けておくか。BusIO はまた後で考える。 @@ -33,7 +33,7 @@ // $6d00000n CPU#n をリセット(?) // $6d000010 全 CPU をリセット -// LUNA88K +// LUNA-88K // 割り込みコントロールレジスタ // $6500_000n // n: CPU ID * 4 (0,4,8,c) @@ -115,14 +115,14 @@ // LUNA-I からの類推及び、OpenBSD mainbus.c に記述あり。OpenBSD のほうは // 低レベルかどうかは不明。 // 3:SPC -// ROM1.2, OpenBSD ともに使用。 +// PROM 1.20, OpenBSD ともに使用。 // 4:LANCE // ROM はまだ不明。OpenBSD は使用。 // 4:拡張スロット // LUNA-I からの類推のみ。不明。 // 5:拡張PC98 -// LUNA-I からの類推のみ。LUNA88K にはスロットがないようなので、 -// LUNA88K2 が必要。 +// LUNA-I からの類推のみ。LUNA-88K にはスロットがないようなので、 +// LUNA-88K2 が必要。 // OpenBSD mainbus.c に記述あり。 // 5:シリアル(7201) // OpenBSD mainbus.c に記述。 @@ -154,7 +154,7 @@ // 要はアドレスバスとR/W信号線しか見ていない。 #include "sysctlr.h" -#include "ethernet.h" +#include "lance.h" #include "mpu88xx0.h" #include "nmi.h" #include "prom.h" @@ -164,12 +164,14 @@ // コンストラクタ SysCtlrDevice::SysCtlrDevice() - : inherited("SystemCtlr") + : inherited(OBJ_INTERRUPT) { + SetName("SystemCtlr"); + AddAlias("SystemCtlr"); AddAlias("SysCtlr"); monitor.func = ToMonitorCallback(&SysCtlrDevice::MonitorUpdate); - monitor.SetSize(25, 10); + monitor.SetSize(40, 12); monitor.Regist(ID_MONITOR_INTERRUPT); } @@ -178,6 +180,24 @@ SysCtlrDevice::~SysCtlrDevice() { } +// 初期化 +bool +SysCtlrDevice::Init() +{ + if (inherited::Init() == false) { + return false; + } + + lance = GetLanceDevice(); + mpu88xx0 = GetMPU88xx0Device(); + nmi = GetNMIDevice(); + sio = GetSIODevice(); + spc = GetSPCDevice(); + sysclk = GetSysClkDevice(); + + return true; +} + // リセット void SysCtlrDevice::ResetHard(bool poweron) @@ -215,15 +235,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; } @@ -237,9 +257,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); } // 設定値を保存 @@ -258,7 +278,7 @@ 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) { @@ -268,13 +288,13 @@ SysCtlrDevice::Write32(uint32 addr, uint // 間隔に書き換えて Start() した後、この書き込み命令から戻ったところの // ExecCallback が time だけ所要サイクルに書き換えて再度 Start() する // ため、時間はともかく幸い ResetCallback() が呼ばれることで動いている。 - gPROM0->ResetHard(false); - gMPU->ResetHard(false); + GetPROM0Device()->ResetHard(false); + mpu->ResetHard(false); ResetHard(false); return 0; } - putlog(0, "未実装書き込み $%08x <- $%08x", addr, data); + putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", addr, data); return 0; } @@ -299,9 +319,8 @@ SysCtlrDevice::Peek8(uint32 addr) case 3: return data & 0xff; default: - break; + __unreachable(); } - __unreachable(); } void @@ -314,9 +333,11 @@ SysCtlrDevice::MonitorUpdate(Monitor *, } table[] = { { "NMI", IntmapNMI }, { "Clock", IntmapSysClk }, + { "XP(Hi)", IntmapXPHigh }, { "SIO", IntmapSIO }, { "Lance", IntmapLance }, { "SPC", IntmapSPC }, + { "XP(Lo)", IntmapXPLow }, { "Soft#0", IntmapSoft0 }, { "Soft#1", IntmapSoft1 }, { "Soft#2", IntmapSoft2 }, @@ -324,20 +345,26 @@ SysCtlrDevice::MonitorUpdate(Monitor *, }; // CPU の割り込み可否は本当は関係ないけど、便宜的に一緒に表示したい - bool ei = gMPU88xx0->GetCPU()->IsIntrEnable(); + bool ei = mpu88xx0->IsIntrEnable(); screen.Clear(); + + // 0 1 2 3 4 + // 01234567890123456789012345678901234567890 + // Lv Device CPU0 Count + y = 0; - // XXX CPU の実装数によってウィンドウ幅を変える。 - // はみ出したところは描画されないのでヘッダは4つ分出力しておく - screen.Print(0, y++, "Lv Device Count CPU0 CPU1 CPU2 CPU3"); + // XXX CPU の実装数によってウィンドウ幅を変えること。 + screen.Print(0, y, "Lv Device CPU0"); + screen.Puts(35, y, "Count"); + y++; for (int i = 0; i < countof(table); i++) { uint32 map = table[i].map; int clz = __builtin_clz(map); int lv = (31 - clz) / 4; screen.Print(0, y, "%d", lv); - screen.Print(2, y, TA::OnOff(intmap & map), "%s", table[i].name); - screen.Print(8, y, "%11" PRIu64, counter[clz]); + screen.Print(3, y, TA::OnOff(intmap & map), "%s", table[i].name); + screen.Print(14, y, "%26s", format_number(counter[clz]).c_str()); // CPU ごとのマスク // XXX 今は CPU は1つしかない @@ -346,11 +373,11 @@ SysCtlrDevice::MonitorUpdate(Monitor *, // 動作としては常にマスクされてて通過しないから問題ないが、 // 見せる分にはマスクされているではなく無効と見せたほうがいい。 if (lv == 1 && map != (IntmapSoft0 << n)) { - screen.Puts(21 + n * 5, y, "----"); + screen.Puts(10 + n * 5, y, "----"); } else if ((cpu[n].intmask & map) == 0) { - screen.Puts(21 + n * 5, y, "Mask"); + screen.Puts(10 + n * 5, y, "Mask"); } else if (!ei) { - screen.Puts(21 + n * 5, y, "IND"); + screen.Puts(10 + n * 5, y, "IND"); } } @@ -362,19 +389,25 @@ SysCtlrDevice::MonitorUpdate(Monitor *, uint32 SysCtlrDevice::GetIntmap(Device *source) const { - if (__predict_true(source == gSysClk)) { + if (__predict_true(source == sysclk)) { return IntmapSysClk; } - if (__predict_true(source == gSIO)) { + if (__predict_true(source == sio)) { return IntmapSIO; } - if (__predict_true(source == gEthernet)) { + if (__predict_true(source == lance)) { return IntmapLance; } - if (__predict_true(source == gSPC)) { + if (__predict_true(source == spc)) { return IntmapSPC; } - if (source == gNMI) { + if (__predict_true(source == DEVICE_XPINT_HIGH)) { + return IntmapXPHigh; + } + if (__predict_true(source == DEVICE_XPINT_LOW)) { + return IntmapXPLow; + } + if (source == nmi) { return IntmapNMI; } PANIC("Unknown interrupt source?"); @@ -402,7 +435,7 @@ SysCtlrDevice::ChangeInterrupt() if (newipl != cpu[i].ipl) { cpu[i].ipl = newipl; // MPU 側は 1 レベルしかない - gMPU->Interrupt(cpu[i].ipl ? 1 : 0); + mpu->Interrupt(cpu[i].ipl ? 1 : 0); } } }