|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: #pragma once
8:
9: #include "device.h"
1.1.1.2 ! root 10: #include "monitor.h"
1.1 root 11:
12: //
13: // 割り込みを受け付けるデバイス
14: // これ自体は IODevice である必要はないが、PEDEC や SysCtlr がこれを
15: // 継承するため。
16: //
17: class InterruptDevice : public IODevice
18: {
19: using inherited = IODevice;
20: public:
21: InterruptDevice();
1.1.1.2 ! root 22: InterruptDevice(const std::string& objname_);
1.1 root 23: virtual ~InterruptDevice() override;
24:
25: // 継承クラスの ResetHard() は保持している割り込み情報を全てキャンセルする。
26: // 各子デバイスはその ResetHard() で NegateINT() を明示的に呼び出して
27: // 割り込みをキャンセルする必要はなく、もし自身で独自に割り込み信号線の
28: // 状態に関する変数を持っていればそれをクリアするだけでよい。
29:
30: // AssertINT()、NegateINT()、ChangeINT() の呼び出し側は、
31: // (アサート中に AssertINT() を呼ぶというような) 現在の状態が
32: // 変わらないような呼び出しをしても構わない。特に副作用はない。
33:
34: // 子デバイスが割り込み信号線をアサートした
35: virtual void AssertINT(Device *source) = 0;
36: // 子デバイスが割り込み信号線をネゲートした
37: virtual void NegateINT(Device *source) = 0;
38:
39: // 子デバイスが割り込み信号線を val の状態に変えた。
40: // true ならアサート、false ならネゲート。
41: void ChangeINT(Device *source, bool val) {
42: if (val) {
43: AssertINT(source);
44: } else {
45: NegateINT(source);
46: }
47: }
48:
49: // MPU からの割り込みアクノリッジに応答する
50: virtual int InterruptAcknowledge(int lv) = 0;
51: };
52:
53: //
54: // m680x0 仮想割り込みコントローラ (共通部)
55: //
56: class M680x0Interrupt : public InterruptDevice
57: {
58: using inherited = InterruptDevice;
59: public:
60: static const int AutoVector = -1; // オートベクタ
61:
62: public:
63: M680x0Interrupt();
64: virtual ~M680x0Interrupt() override;
65:
66: void ResetHard() override;
67:
68: void AssertINT(Device *source) override;
69: void NegateINT(Device *source) override;
70:
71: protected:
72: // Intmap は 32bit のビットマップ値で、値は機種ごとに定義する。
73: // 1つの割り込みレベルにつき 4つまでデバイスをマッピングでき、また、
74: // 同一レベル内での複数のデバイスの割り込み信号線の状態を独立して保持
75: // できるようにするため。
76: //
77: // 3 2 1 0
78: // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
79: // +-------+-------+-------+-------+-------+-------+-------+-------+
80: // |7 7 7 7|6 6 6 6|5 5 5 5|4 4 4 4|3 3 3 3|2 2 2 2|1 1 1 1| %0001 |
81: // +-------+-------+-------+-------+-------+-------+-------+-------+
82: //
83: // bit31-4 でレベル 7-1 の割り込みを表す。
84: // アサートされている信号線のうち最もレベルの高いものは以下で求まる。
85: // ipl = (31 - clz(intmap)) / 4
86: // 例えば bit30 と bit20 が立っている場合 (これは割り込みレベル 7 と 5 が
87: // 同時に要求されている状態)、最高レベルは (31 - 1) / 4 = 7 となる。
88: // また __builtin_clz(0) は未定義なので使わない最下位ビットを常に立てて
89: // おくことで、割り込みなし(上位28bitがすべて0)の場合でもこの式が使える。
90:
91: // デバイスから Intmap 値を引く。
92: virtual uint32 GetIntmap(Device *source) const = 0;
93:
94: // 現在の割り込みレベル
95: int ipl {};
96:
97: // 割り込みマップ
98: uint32 intmap {};
99:
100: // 割り込み回数 (アサートのエッジでカウントアップする)
101: // [0] が Intmap の bit31 割り込みのカウント。
102: // [27] が Intmap の bit 4 割り込みのカウント。
103: uint32 counter[28] {};
104: };
105:
106: //
107: // X68k 仮想割り込みコントローラ
108: //
109: // Level
110: // 7 INTERRUPT スイッチ
111: // 6 MFP
112: // 5 SCC
113: // 4 (拡張ボード)
114: // 3 DMAC
115: // 2 (拡張ボード)
116: // 1 PEDEC <--+-- SPC
117: // +-- HDD (SASI)
118: // +-- FDC
119: // +-- FDD
120: // +-- PRN
121: //
122: class X68030Interrupt : public M680x0Interrupt
123: {
124: using inherited = M680x0Interrupt;
125:
126: // 割り込みマップ 76543210
127: static const uint32 IntmapNMI = 0x80000000;
128: static const uint32 IntmapMFP = 0x08000000;
129: static const uint32 IntmapSCC = 0x00800000;
130: static const uint32 IntmapDMAC = 0x00008000;
131: static const uint32 IntmapPEDEC = 0x00000080;
132:
133: public:
134: X68030Interrupt();
135: virtual ~X68030Interrupt() override;
136:
137: int InterruptAcknowledge(int lv) override;
138:
139: private:
140: uint32 GetIntmap(Device *soruce) const override;
1.1.1.2 ! root 141:
! 142: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
! 143:
! 144: Monitor monitor { this };
1.1 root 145: };
146:
147: //
148: // LUNA-I 仮想割り込みコントローラ
149: //
150: // Level
151: // 7
152: // 6 SIO
153: // 5 SystemClock
154: // 4 (XP high)
155: // 3 Lance
156: // 2 SPC
157: // 1 (XP low)
158: //
159: class LunaInterrupt : public M680x0Interrupt
160: {
161: using inherited = M680x0Interrupt;
162:
163: // 割り込みマップ 76543210
164: static const uint32 IntmapSIO = 0x08000000;
165: static const uint32 IntmapSysClk = 0x00800000;
166: static const uint32 IntmapLance = 0x00008000;
167: static const uint32 IntmapSPC = 0x00000800;
168:
169: public:
170: LunaInterrupt();
171: virtual ~LunaInterrupt() override;
172:
173: int InterruptAcknowledge(int lv) override;
174:
175: private:
176: uint32 GetIntmap(Device *source) const override;
1.1.1.2 ! root 177:
! 178: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
! 179:
! 180: Monitor monitor { this };
1.1 root 181: };
182:
183: // LUNA88K は sysctlr.cpp 参照。
184:
185: extern std::unique_ptr<InterruptDevice> gInterrupt;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.