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