|
|
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.2 root 90: PEDECDevice::Read(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?
! 110: return data;
1.1 root 111: }
112:
1.1.1.9 ! root 113: busdata
1.1.1.2 root 114: PEDECDevice::Write(uint32 offset, uint32 data)
1.1 root 115: {
1.1.1.2 root 116: switch (offset) {
1.1 root 117: case 0: // $E9C001 割り込みマスク
1.1.1.9 ! root 118: intmap_enable = IntmapSPC;
! 119: intmap_enable |= (data & 0x08) ? IntmapHDD : 0;
! 120: intmap_enable |= (data & 0x04) ? IntmapFDC : 0;
! 121: intmap_enable |= (data & 0x02) ? IntmapFDD : 0;
! 122: intmap_enable |= (data & 0x01) ? IntmapPRT : 0;
1.1 root 123:
1.1.1.6 root 124: putlog(1, "Set Interrupt Mask HDD=%d FDC=%d FDD=%d PRT=%d",
1.1.1.9 ! root 125: ((intmap_enable & IntmapHDD) ? 1 : 0),
! 126: ((intmap_enable & IntmapFDC) ? 1 : 0),
! 127: ((intmap_enable & IntmapFDD) ? 1 : 0),
! 128: ((intmap_enable & IntmapPRT) ? 1 : 0));
! 129: break;
1.1 root 130:
131: case 1: // $E9C003 割り込みベクタ
132: vector = data & 0xfc;
1.1.1.6 root 133: putlog(1, "Set Interrupt Vector $%02x", vector);
1.1.1.9 ! root 134: break;
1.1 root 135:
136: default:
1.1.1.9 ! root 137: break;
1.1 root 138: }
1.1.1.9 ! root 139:
! 140: // XXX wait?
! 141: return 0;
1.1 root 142: }
143:
1.1.1.9 ! root 144: busdata
1.1.1.2 root 145: PEDECDevice::Peek(uint32 offset)
1.1 root 146: {
1.1.1.2 root 147: switch (offset) {
1.1 root 148: case 0:
149: return GetStat();
150:
151: case 1:
152: // 書き込み専用
153: return 0xff;
154:
155: default:
156: return 0xff;
157: }
158: }
159:
1.1.1.4 root 160: void
161: PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y)
162: {
1.1.1.9 ! root 163: for (uint32 map : disp_list) {
1.1.1.4 root 164: int clz = __builtin_clz(map);
1.1.1.9 ! root 165: screen.Puts(4, y, TA::OnOff(intmap_status & map), GetIntName(map));
! 166: if (intr_level >= 1 || (intmap_enable & map) == 0) {
1.1.1.8 root 167: screen.Puts(11, y, "Mask");
1.1.1.4 root 168: }
1.1.1.9 ! root 169: uint64 cnt = counter[clz];
! 170: if (__predict_false(map == IntmapFDD)) {
! 171: // FDD は4つの和
! 172: cnt += counter[clz + 1] + counter[clz + 2] + counter[clz + 3];
! 173: }
! 174: screen.Print(15, y, "%26s", format_number(cnt).c_str());
1.1.1.4 root 175: y++;
176: }
177: }
178:
1.1 root 179: // 割り込みステータスレジスタの値を取得。
180: // (Peek からも呼ばれるので副作用を持たせてはいけない)
181: uint32
182: PEDECDevice::GetStat() const
183: {
184: uint32 data = 0;
1.1.1.9 ! root 185: data |= (intmap_status & IntmapFDC) ? 0x80 : 0;
! 186: data |= (intmap_status & IntmapFDD) ? 0x40 : 0;
! 187: data |= (intmap_status & IntmapPRT) ? 0x20 : 0;
! 188: data |= (intmap_status & IntmapHDD) ? 0x10 : 0;
! 189: data |= (intmap_enable & IntmapHDD) ? 0x08 : 0;
! 190: data |= (intmap_enable & IntmapFDC) ? 0x04 : 0;
! 191: data |= (intmap_enable & IntmapFDD) ? 0x02 : 0;
! 192: data |= (intmap_enable & IntmapPRT) ? 0x01 : 0;
1.1 root 193: return data;
194: }
195:
1.1.1.4 root 196: // 割り込み信号線の状態を変える
1.1 root 197: void
1.1.1.4 root 198: PEDECDevice::ChangeInterrupt()
1.1 root 199: {
1.1.1.4 root 200: #if 0 // こんなログ出したいかも
1.1 root 201: // ログ表示のためだけ
1.1.1.9 ! root 202: if ((intmap_enable & IntmapFDC)) {
1.1 root 203: putlog(1, "FDC からの割り込み要求");
204: } else {
205: putlog(2, "FDC からの割り込み要求(マスク)");
206: }
1.1.1.4 root 207: #endif
1.1 root 208:
1.1.1.9 ! root 209: uint32 stat = (intmap_status & intmap_enable);
1.1.1.7 root 210: interrupt->ChangeINT(this, stat);
1.1 root 211: }
212:
213: // 割り込みアクノリッジ
1.1.1.9 ! root 214: busdata
1.1 root 215: PEDECDevice::InterruptAcknowledge(int lv)
216: {
1.1.1.9 ! root 217: uint32 stat = (intmap_status & intmap_enable);
1.1 root 218:
219: // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
220: // SPC を優先しておくのでいいだろう。
221: if ((stat & IntmapSPC)) {
222: // XXX PEDEC のベクタに影響されるか?
223: return 0x6c;
224: }
225:
226: if ((stat & IntmapFDC)) {
227: return vector + 0;
1.1.1.6 root 228: } else if ((stat & IntmapFDD)) {
229: return vector + 1;
1.1 root 230: } else {
1.1.1.9 ! root 231: return busdata::BusErr;
1.1.1.6 root 232: }
1.1.1.4 root 233: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.