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