--- nono/vm/sysctlr.h 2026/04/29 17:04:36 1.1.1.1 +++ nono/vm/sysctlr.h 2026/04/29 17:05:50 1.1.1.12 @@ -4,32 +4,82 @@ // Licensed under nono-license.txt // -// LUNA88K のシステムコントローラのような何か +// +// LUNA-88K のシステムコントローラのような何か +// #pragma once -#include "device.h" +#include "interrupt.h" + +class MPU88xx0Device; -class SysCtlrDevice - : public IODevice +class SysCtlrDevice : public InterruptDevice { - using inherited = IODevice; + using inherited = InterruptDevice; + + // 割り込みマップ 76543210 + static const uint32 IntmapNMI = 0x80000000; + static const uint32 IntmapSysClk = 0x08000000; + static const uint32 IntmapSIO = 0x00800000; + static const uint32 IntmapXPHigh = 0x00400000; + static const uint32 IntmapLance = 0x00080000; + static const uint32 IntmapSPC = 0x00008000; + static const uint32 IntmapXPLow = 0x00000080; + static const uint32 IntmapSoft = 0x00000040; + public: SysCtlrDevice(); ~SysCtlrDevice() override; - bool MonitorUpdate() override; + bool Init() override; + void ResetHard(bool poweron) override; - uint64 Read32(uint32 addr) override; - uint64 Write32(uint32 addr, uint32 data) override; - uint64 Peek8(uint32 addr) override; + busdata Read(busaddr addr) override; + busdata Write(busaddr addr, uint32 data) override; + busdata Peek1(uint32 addr) override; + + // 割り込みマスク設定 + void WriteIntMask(uint32 n, uint32 data); + + // InterruptDevice インタフェース + busdata InterruptAcknowledge(int lv) override; - uint8 GetIntMask(int id) const { return intmask[id]; } - void TellIntLevel(int id, int level) { intlevel[id] |= level; } private: - uint8 intmask[4] {}; - // 発生した割り込みのレベルビットマップ - uint8 intlevel[4] {}; + // Peek1() の下請け + uint32 Peek4(uint32 addr) const; + + // 割り込み状態を更新 + void ChangeInterrupt() override; + + // マスク設定レジスタの書き込み値から内部用マスクを作成 + static uint32 MakeIntMask(uint32 data, uint n); + + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + + // CPU ごとのパラメータ + struct { + // 割り込みマスク (設定値) + // 書き込み時の値をそのまま保持しておくので bit31-26 のみ有効。他は %0。 + uint32 maskval; + + // 内部用 intmap に対する割り込みマスク + uint32 intmask; + + // 現在の最高位の割り込みレベル + int ipl; + + // ソフトウェア割り込みの Intmap (アサート中なら IntmapSoft) + uint32 softint; + + // ソフトウェア割り込み回数 + uint64 softint_count; + } cpu[4] {}; + + MPU88xx0Device *mpu88xx0 {}; + + Monitor *monitor {}; }; -extern std::unique_ptr gSysCtlr; +// 参照はここではなく GetInterruptDevice() を使用する +// (LUNA-88K ではこれがメインの割り込みコントローラなので)