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