|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
1.1.1.5 root 7: //
8: // PEDEC
9: //
10:
11: // IODevice
12: // |
13: // +-- InterruptDevice (割り込みコントローラの共通部)
14: // |
15: // +-- M680x0Interrupt (m68k 割り込みコントローラの共通部)
16: // | |
17: // | +-- X68030Interrupt (X68030 の割り込みコントローラ)
18: // | +-- LunaInterrupt (LUNA-I の割り込みコントローラ)
19: // |
20: // | +-------------+
21: // +--| PEDECDevice | (X68030 の Lv1 担当コントローラ)
22: // | +-------------+
23: // |
1.1.1.7 root 24: // +-- SysCtlrDevice (LUNA-88K の割り込みコントローラ)
1.1.1.5 root 25:
1.1 root 26: #include "pedec.h"
27: #include "fdc.h"
1.1.1.6 root 28: #include "fdd.h"
1.1.1.11! root 29: #include "mainapp.h"
1.1 root 30: #include "spc.h"
31:
1.1.1.5 root 32: // コンストラクタ
1.1 root 33: PEDECDevice::PEDECDevice()
1.1.1.7 root 34: : inherited(OBJ_PEDEC)
1.1 root 35: {
36: }
37:
1.1.1.5 root 38: // デストラクタ
1.1 root 39: PEDECDevice::~PEDECDevice()
40: {
1.1.1.7 root 41: }
42:
43: // 初期化
44: bool
45: PEDECDevice::Init()
46: {
47: if (inherited::Init() == false) {
48: return false;
49: }
50:
51: interrupt = GetInterruptDevice();
1.1.1.9 root 52:
53: // 検索順
54: RegistINT(IntmapSPC, "SPC", GetSPCDevice());
55: RegistINT(IntmapFDC, "FDC", GetFDCDevice());
56: RegistINT(IntmapHDD, "HDD", NULL);
57: RegistINT(IntmapPRT, "PRT", NULL);
58: // FDD は4本を共有しているのでいろいろ特別扱い。
59: RegistINT(IntmapFDD0, "FDD0", gMainApp.FindObject<FDDDevice>(OBJ_FDD(0)));
60: RegistINT(IntmapFDD1, "FDD1", gMainApp.FindObject<FDDDevice>(OBJ_FDD(1)));
61: RegistINT(IntmapFDD2, "FDD2", gMainApp.FindObject<FDDDevice>(OBJ_FDD(2)));
62: RegistINT(IntmapFDD3, "FDD3", gMainApp.FindObject<FDDDevice>(OBJ_FDD(3)));
63: // 名前表示用
64: RegistINT(IntmapFDD, "FDD", NULL);
65:
66: // 表示順
67: disp_list = {
68: IntmapSPC,
69: IntmapFDC,
70: IntmapFDD,
71: IntmapHDD,
72: IntmapPRT,
73: };
1.1.1.7 root 74:
75: return true;
1.1 root 76: }
77:
1.1.1.5 root 78: // リセット
1.1 root 79: void
1.1.1.5 root 80: PEDECDevice::ResetHard(bool poweron)
1.1 root 81: {
1.1.1.5 root 82: inherited::ResetHard(poweron);
1.1.1.4 root 83:
1.1.1.9 root 84: intmap_enable = IntmapSPC;
85: ChangeInterrupt();
86:
1.1 root 87: // XXX vector
88: }
89:
1.1.1.9 root 90: busdata
1.1.1.10 root 91: PEDECDevice::ReadPort(uint32 offset)
1.1 root 92: {
1.1.1.9 root 93: busdata data;
94:
1.1.1.2 root 95: switch (offset) {
1.1 root 96: case 0: // $E9C001 割り込みステータス
1.1.1.9 root 97: data = GetStat();
98: break;
1.1 root 99:
100: case 1: // $E9C003 割り込みベクタ
101: // 書き込み専用
1.1.1.9 root 102: data = 0xff;
103: break;
1.1 root 104:
105: default:
1.1.1.9 root 106: data = 0xff;
107: break;
1.1 root 108: }
1.1.1.9 root 109:
110: // XXX wait?
1.1.1.10 root 111: data |= BusData::Size1;
1.1.1.9 root 112: return data;
1.1 root 113: }
114:
1.1.1.9 root 115: busdata
1.1.1.10 root 116: PEDECDevice::WritePort(uint32 offset, uint32 data)
1.1 root 117: {
1.1.1.2 root 118: switch (offset) {
1.1 root 119: case 0: // $E9C001 割り込みマスク
1.1.1.9 root 120: intmap_enable = IntmapSPC;
121: intmap_enable |= (data & 0x08) ? IntmapHDD : 0;
122: intmap_enable |= (data & 0x04) ? IntmapFDC : 0;
123: intmap_enable |= (data & 0x02) ? IntmapFDD : 0;
124: intmap_enable |= (data & 0x01) ? IntmapPRT : 0;
1.1 root 125:
1.1.1.10 root 126: putlog(1, "Set Interrupt Mask HDD=%u FDC=%u FDD=%u PRT=%u",
1.1.1.9 root 127: ((intmap_enable & IntmapHDD) ? 1 : 0),
128: ((intmap_enable & IntmapFDC) ? 1 : 0),
129: ((intmap_enable & IntmapFDD) ? 1 : 0),
130: ((intmap_enable & IntmapPRT) ? 1 : 0));
131: break;
1.1 root 132:
133: case 1: // $E9C003 割り込みベクタ
134: vector = data & 0xfc;
1.1.1.6 root 135: putlog(1, "Set Interrupt Vector $%02x", vector);
1.1.1.9 root 136: break;
1.1 root 137:
138: default:
1.1.1.9 root 139: break;
1.1 root 140: }
1.1.1.9 root 141:
142: // XXX wait?
1.1.1.10 root 143: busdata r = BusData::Size1;
144: return r;
1.1 root 145: }
146:
1.1.1.9 root 147: busdata
1.1.1.10 root 148: PEDECDevice::PeekPort(uint32 offset)
1.1 root 149: {
1.1.1.2 root 150: switch (offset) {
1.1 root 151: case 0:
152: return GetStat();
153:
154: case 1:
155: // 書き込み専用
156: return 0xff;
157:
158: default:
159: return 0xff;
160: }
161: }
162:
1.1.1.10 root 163: bool
164: PEDECDevice::PokePort(uint32 offset, uint32 data)
165: {
166: return false;
167: }
168:
1.1.1.4 root 169: void
170: PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y)
171: {
1.1.1.9 root 172: for (uint32 map : disp_list) {
1.1.1.4 root 173: int clz = __builtin_clz(map);
1.1.1.9 root 174: screen.Puts(4, y, TA::OnOff(intmap_status & map), GetIntName(map));
175: if (intr_level >= 1 || (intmap_enable & map) == 0) {
1.1.1.8 root 176: screen.Puts(11, y, "Mask");
1.1.1.4 root 177: }
1.1.1.9 root 178: uint64 cnt = counter[clz];
179: if (__predict_false(map == IntmapFDD)) {
180: // FDD は4つの和
181: cnt += counter[clz + 1] + counter[clz + 2] + counter[clz + 3];
182: }
183: screen.Print(15, y, "%26s", format_number(cnt).c_str());
1.1.1.4 root 184: y++;
185: }
186: }
187:
1.1 root 188: // 割り込みステータスレジスタの値を取得。
189: // (Peek からも呼ばれるので副作用を持たせてはいけない)
190: uint32
191: PEDECDevice::GetStat() const
192: {
193: uint32 data = 0;
1.1.1.9 root 194: data |= (intmap_status & IntmapFDC) ? 0x80 : 0;
195: data |= (intmap_status & IntmapFDD) ? 0x40 : 0;
196: data |= (intmap_status & IntmapPRT) ? 0x20 : 0;
197: data |= (intmap_status & IntmapHDD) ? 0x10 : 0;
198: data |= (intmap_enable & IntmapHDD) ? 0x08 : 0;
199: data |= (intmap_enable & IntmapFDC) ? 0x04 : 0;
200: data |= (intmap_enable & IntmapFDD) ? 0x02 : 0;
201: data |= (intmap_enable & IntmapPRT) ? 0x01 : 0;
1.1 root 202: return data;
203: }
204:
1.1.1.4 root 205: // 割り込み信号線の状態を変える
1.1 root 206: void
1.1.1.4 root 207: PEDECDevice::ChangeInterrupt()
1.1 root 208: {
1.1.1.4 root 209: #if 0 // こんなログ出したいかも
1.1 root 210: // ログ表示のためだけ
1.1.1.9 root 211: if ((intmap_enable & IntmapFDC)) {
1.1 root 212: putlog(1, "FDC からの割り込み要求");
213: } else {
214: putlog(2, "FDC からの割り込み要求(マスク)");
215: }
1.1.1.4 root 216: #endif
1.1 root 217:
1.1.1.9 root 218: uint32 stat = (intmap_status & intmap_enable);
1.1.1.7 root 219: interrupt->ChangeINT(this, stat);
1.1 root 220: }
221:
222: // 割り込みアクノリッジ
1.1.1.9 root 223: busdata
1.1 root 224: PEDECDevice::InterruptAcknowledge(int lv)
225: {
1.1.1.9 root 226: uint32 stat = (intmap_status & intmap_enable);
1.1 root 227:
228: // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
229: // SPC を優先しておくのでいいだろう。
230: if ((stat & IntmapSPC)) {
231: // XXX PEDEC のベクタに影響されるか?
232: return 0x6c;
233: }
234:
235: if ((stat & IntmapFDC)) {
236: return vector + 0;
1.1.1.6 root 237: } else if ((stat & IntmapFDD)) {
238: return vector + 1;
1.1 root 239: } else {
1.1.1.10 root 240: return BusData::BusErr;
1.1.1.6 root 241: }
1.1.1.4 root 242: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.