--- nono/vm/interrupt.h 2026/04/29 17:05:06 1.1.1.3 +++ nono/vm/interrupt.h 2026/04/29 17:05:17 1.1.1.5 @@ -4,30 +4,47 @@ // Licensed under nono-license.txt // +// +// 割り込みコントローラ +// + #pragma once #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 がこれを // 継承するため。 -// class InterruptDevice : public IODevice { using inherited = IODevice; public: InterruptDevice(); - InterruptDevice(const std::string& objname_); + InterruptDevice(int objid_); virtual ~InterruptDevice() override; - void ResetHard() override; - // 継承クラスの ResetHard() は保持している割り込み情報を全てキャンセルする。 // 各子デバイスはその ResetHard() で NegateINT() を明示的に呼び出して // 割り込みをキャンセルする必要はなく、もし自身で独自に割り込み信号線の // 状態に関する変数を持っていればそれをクリアするだけでよい。 + void ResetHard(bool poweron) override; // AssertINT()、NegateINT()、ChangeINT() の呼び出し側は、 // (アサート中に AssertINT() を呼ぶというような) 現在の状態が @@ -82,7 +99,7 @@ class InterruptDevice : public IODevice // // ipl = (31 - __builtin_clz(intmap)) / 4; // - // LUNA88K の外部割り込みコントローラであるシステムコントローラも + // LUNA-88K の外部割り込みコントローラであるシステムコントローラも // 概ねこれに近いので、sysctlr もこの構造を使う。 // // PEDEC は 7レベル分けする必要ないので、適当に割り当ててある。 @@ -101,9 +118,7 @@ class InterruptDevice : public IODevice uint64 counter[28] {}; }; -// // m680x0 仮想割り込みコントローラ (共通部) -// class M680x0Interrupt : public InterruptDevice { using inherited = InterruptDevice; @@ -114,7 +129,8 @@ class M680x0Interrupt : public Interrupt M680x0Interrupt(); virtual ~M680x0Interrupt() override; - void ResetHard() override; + bool Init() override; + void ResetHard(bool poweron) override; protected: void ChangeInterrupt() override; @@ -123,7 +139,6 @@ class M680x0Interrupt : public Interrupt int ipl {}; }; -// // X68k 仮想割り込みコントローラ // // Level @@ -154,6 +169,7 @@ class X68030Interrupt : public M680x0Int X68030Interrupt(); virtual ~X68030Interrupt() override; + bool Init() override; int InterruptAcknowledge(int lv) override; private: @@ -161,10 +177,15 @@ class X68030Interrupt : public M680x0Int DECLARE_MONITOR_CALLBACK(MonitorUpdate); + DMACDevice *dmac {}; + MFPDevice *mfp {}; + NMIDevice *nmi {}; + PEDECDevice *pedec {}; + SCCDevice *scc {}; + Monitor monitor { this }; }; -// // LUNA-I 仮想割り込みコントローラ // // Level @@ -181,15 +202,19 @@ class LunaInterrupt : public M680x0Inter using inherited = M680x0Interrupt; // 割り込みマップ 76543210 + 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: @@ -197,9 +222,61 @@ class LunaInterrupt : public M680x0Inter 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 std::unique_ptr gInterrupt; +static inline InterruptDevice *GetInterruptDevice() { + return Object::GetObject(OBJ_INTERRUPT); +}