--- nono/vm/sysctlr.h 2026/04/29 17:04:36 1.1.1.1 +++ nono/vm/sysctlr.h 2026/04/29 17:05:10 1.1.1.6 @@ -4,32 +4,69 @@ // Licensed under nono-license.txt // +// // LUNA88K のシステムコントローラのような何か +// #pragma once -#include "device.h" +#include "interrupt.h" -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 IntmapLance = 0x00080000; + static const uint32 IntmapSPC = 0x00008000; + static const uint32 IntmapSoft3 = 0x00000080; + static const uint32 IntmapSoft2 = 0x00000040; + static const uint32 IntmapSoft1 = 0x00000020; + static const uint32 IntmapSoft0 = 0x00000010; + public: SysCtlrDevice(); - ~SysCtlrDevice() override; + virtual ~SysCtlrDevice() override; - bool MonitorUpdate() override; + void ResetHard(bool poweron) override; uint64 Read32(uint32 addr) override; uint64 Write32(uint32 addr, uint32 data) override; uint64 Peek8(uint32 addr) override; - uint8 GetIntMask(int id) const { return intmask[id]; } - void TellIntLevel(int id, int level) { intlevel[id] |= level; } + // InterruptDevice インタフェース + int InterruptAcknowledge(int lv) override; + private: - uint8 intmask[4] {}; - // 発生した割り込みのレベルビットマップ - uint8 intlevel[4] {}; + // デバイスから Intmap 値を引く + uint32 GetIntmap(Device *source) const override; + + // 割り込み状態を更新 + void ChangeInterrupt() override; + + // マスク設定レジスタの書き込み値から内部用マスクを作成 + static uint32 MakeIntMask(uint32 data, int n); + + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + + // CPU ごとのパラメータ + struct { + // 割り込みマスク (設定値) + // 書き込み時の値をそのまま保持しておくので bit31-26 のみ有効。他は %0。 + uint32 maskval; + + // 内部用 intmap に対する割り込みマスク + uint32 intmask; + + // 現在の最高位の割り込みレベル + int ipl; + } cpu[4] {}; + + Monitor monitor { this }; }; -extern std::unique_ptr gSysCtlr; +// グローバルインスタンスはここではなく gInterrupt を使用する +// (LUNA88K ではこれがメインの割り込みコントローラなので)