--- nono/vm/interrupt.h 2026/04/29 17:05:10 1.1.1.4 +++ nono/vm/interrupt.h 2026/04/29 17:05:17 1.1.1.5 @@ -13,6 +13,22 @@ #include "device.h" #include "monitor.h" +// XP からの割り込み用。 +// これだけ1デバイスで2本あるので、仕方なく識別子を用意。 +#define DEVICE_XPINT_HIGH ((Device *)(intptr_t)1) +#define DEVICE_XPINT_LOW ((Device *)(intptr_t)2) + +class DMACDevice; +class LanceDevice; +class MFPDevice; +class NewsCtlrDevice; +class NMIDevice; +class PEDECDevice; +class SCCDevice; +class SIODevice; +class SPCDevice; +class SysClkDevice; + // 割り込みを受け付けるデバイス。 // これ自体は IODevice である必要はないが、PEDEC や SysCtlr がこれを // 継承するため。 @@ -21,7 +37,7 @@ class InterruptDevice : public IODevice using inherited = IODevice; public: InterruptDevice(); - InterruptDevice(const std::string& objname_); + InterruptDevice(int objid_); virtual ~InterruptDevice() override; // 継承クラスの ResetHard() は保持している割り込み情報を全てキャンセルする。 @@ -83,7 +99,7 @@ class InterruptDevice : public IODevice // // ipl = (31 - __builtin_clz(intmap)) / 4; // - // LUNA88K の外部割り込みコントローラであるシステムコントローラも + // LUNA-88K の外部割り込みコントローラであるシステムコントローラも // 概ねこれに近いので、sysctlr もこの構造を使う。 // // PEDEC は 7レベル分けする必要ないので、適当に割り当ててある。 @@ -113,6 +129,7 @@ class M680x0Interrupt : public Interrupt M680x0Interrupt(); virtual ~M680x0Interrupt() override; + bool Init() override; void ResetHard(bool poweron) override; protected: @@ -152,6 +169,7 @@ class X68030Interrupt : public M680x0Int X68030Interrupt(); virtual ~X68030Interrupt() override; + bool Init() override; int InterruptAcknowledge(int lv) override; private: @@ -159,6 +177,12 @@ class X68030Interrupt : public M680x0Int DECLARE_MONITOR_CALLBACK(MonitorUpdate); + DMACDevice *dmac {}; + MFPDevice *mfp {}; + NMIDevice *nmi {}; + PEDECDevice *pedec {}; + SCCDevice *scc {}; + Monitor monitor { this }; }; @@ -181,23 +205,78 @@ class LunaInterrupt : public M680x0Inter static const uint32 IntmapNMI = 0x80000000; static const uint32 IntmapSIO = 0x08000000; static const uint32 IntmapSysClk = 0x00800000; + static const uint32 IntmapXPHigh = 0x00400000; static const uint32 IntmapLance = 0x00008000; static const uint32 IntmapSPC = 0x00000800; + static const uint32 IntmapXPLow = 0x00000080; public: LunaInterrupt(); virtual ~LunaInterrupt() override; + bool Init() override; + int InterruptAcknowledge(int lv) override; + + private: + uint32 GetIntmap(Device *source) const override; + + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + + LanceDevice *lance {}; + NMIDevice *nmi {}; + SIODevice *sio {}; + SPCDevice *spc {}; + SysClkDevice *sysclk {}; + + Monitor monitor { this }; +}; + +// NEWS 仮想割り込みコントローラ +// +// Level +// 7 +// 6 Timer +// 5 SCC(vectored) +// 4 SIC, Lance +// 3 +// 2 +// 1 +// +class NewsInterrupt : public M680x0Interrupt +{ + using inherited = M680x0Interrupt; + + // 割り込みマップ 76543210 + static const uint32 IntmapNMI = 0x80000000; + static const uint32 IntmapTimer = 0x08000000; + static const uint32 IntmapSCC = 0x00800000; + static const uint32 IntmapSIC = 0x00080000; + static const uint32 IntmapLance = 0x00040000; + + public: + NewsInterrupt(); + virtual ~NewsInterrupt() override; + + bool Init() override; int InterruptAcknowledge(int lv) override; + // 割り込みステータスを返す (NewsCtlr から呼ばれる) + uint8 PeekStatus() const; + private: uint32 GetIntmap(Device *source) const override; DECLARE_MONITOR_CALLBACK(MonitorUpdate); + LanceDevice *lance {}; + NewsCtlrDevice *newsctlr {}; + SCCDevice *scc {}; + Monitor monitor { this }; }; -// LUNA88K は sysctlr.cpp 参照。 +// LUNA-88K は sysctlr.cpp 参照。 -extern InterruptDevice *gInterrupt; +static inline InterruptDevice *GetInterruptDevice() { + return Object::GetObject(OBJ_INTERRUPT); +}