|
|
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: fdc = GetFDCDevice();
! 51: interrupt = GetInterruptDevice();
! 52: spc = GetSPCDevice();
! 53:
! 54: return true;
1.1 root 55: }
56:
1.1.1.5 root 57: // リセット
1.1 root 58: void
1.1.1.5 root 59: PEDECDevice::ResetHard(bool poweron)
1.1 root 60: {
1.1.1.5 root 61: inherited::ResetHard(poweron);
1.1.1.4 root 62:
63: intmap_enabled = IntmapSPC;
1.1 root 64: // XXX vector
65: }
66:
67: uint64
1.1.1.2 root 68: PEDECDevice::Read(uint32 offset)
1.1 root 69: {
1.1.1.2 root 70: switch (offset) {
1.1 root 71: case 0: // $E9C001 割り込みステータス
72: return GetStat();
73:
74: case 1: // $E9C003 割り込みベクタ
75: // 書き込み専用
76: return 0xff;
77:
78: default:
79: return 0xff;
80: }
81: }
82:
83: uint64
1.1.1.2 root 84: PEDECDevice::Write(uint32 offset, uint32 data)
1.1 root 85: {
1.1.1.2 root 86: switch (offset) {
1.1 root 87: case 0: // $E9C001 割り込みマスク
1.1.1.4 root 88: intmap_enabled = IntmapSPC;
89: intmap_enabled |= (data & 0x08) ? IntmapHDD : 0;
90: intmap_enabled |= (data & 0x04) ? IntmapFDC : 0;
91: intmap_enabled |= (data & 0x02) ? IntmapFDD : 0;
92: intmap_enabled |= (data & 0x01) ? IntmapPRT : 0;
1.1 root 93:
1.1.1.6 root 94: putlog(1, "Set Interrupt Mask HDD=%d FDC=%d FDD=%d PRT=%d",
1.1.1.4 root 95: ((intmap_enabled & IntmapHDD) ? 1 : 0),
96: ((intmap_enabled & IntmapFDC) ? 1 : 0),
97: ((intmap_enabled & IntmapFDD) ? 1 : 0),
98: ((intmap_enabled & IntmapPRT) ? 1 : 0));
1.1 root 99: return 0;
100:
101: case 1: // $E9C003 割り込みベクタ
102: vector = data & 0xfc;
1.1.1.6 root 103: putlog(1, "Set Interrupt Vector $%02x", vector);
1.1 root 104: return 0;
105:
106: default:
107: return 0;
108: }
109: }
110:
111: uint64
1.1.1.2 root 112: PEDECDevice::Peek(uint32 offset)
1.1 root 113: {
1.1.1.2 root 114: switch (offset) {
1.1 root 115: case 0:
116: return GetStat();
117:
118: case 1:
119: // 書き込み専用
120: return 0xff;
121:
122: default:
123: return 0xff;
124: }
125: }
126:
1.1.1.4 root 127: void
128: PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y)
129: {
130: struct {
131: const char *name;
132: uint32 map;
133: } table[] = {
134: { "SPC", IntmapSPC },
135: { "FDC", IntmapFDC },
136: { "FDD", IntmapFDD },
137: { "HDD", IntmapHDD },
138: { "PRT", IntmapPRT },
139: };
140:
141: for (int i = 0; i < countof(table); i++) {
142: uint32 map = table[i].map;
143: int clz = __builtin_clz(map);
1.1.1.7 ! root 144: screen.Puts(4, y, TA::OnOff(intmap & map), table[i].name);
1.1.1.4 root 145: if (intr_level >= 1 || (intmap_enabled & map) == 0) {
1.1.1.7 ! root 146: screen.Puts(10, y, "Mask");
1.1.1.4 root 147: }
1.1.1.7 ! root 148: screen.Print(14, y, "%26s", format_number(counter[clz]).c_str());
1.1.1.4 root 149: y++;
150: }
151: }
152:
1.1 root 153: // 割り込みステータスレジスタの値を取得。
154: // (Peek からも呼ばれるので副作用を持たせてはいけない)
155: uint32
156: PEDECDevice::GetStat() const
157: {
158: uint32 data = 0;
1.1.1.4 root 159: data |= (intmap & IntmapFDC) ? 0x80 : 0;
160: data |= (intmap & IntmapFDD) ? 0x40 : 0;
161: data |= (intmap & IntmapPRT) ? 0x20 : 0;
162: data |= (intmap & IntmapHDD) ? 0x10 : 0;
163: data |= (intmap_enabled & IntmapHDD) ? 0x08 : 0;
164: data |= (intmap_enabled & IntmapFDC) ? 0x04 : 0;
165: data |= (intmap_enabled & IntmapFDD) ? 0x02 : 0;
166: data |= (intmap_enabled & IntmapPRT) ? 0x01 : 0;
1.1 root 167: return data;
168: }
169:
1.1.1.4 root 170: // 割り込み信号線の状態を変える
1.1 root 171: void
1.1.1.4 root 172: PEDECDevice::ChangeInterrupt()
1.1 root 173: {
1.1.1.4 root 174: #if 0 // こんなログ出したいかも
1.1 root 175: // ログ表示のためだけ
1.1.1.4 root 176: if ((intmap_enabled & IntmapFDC)) {
1.1 root 177: putlog(1, "FDC からの割り込み要求");
178: } else {
179: putlog(2, "FDC からの割り込み要求(マスク)");
180: }
1.1.1.4 root 181: #endif
1.1 root 182:
1.1.1.4 root 183: uint32 stat = (intmap & intmap_enabled);
1.1.1.7 ! root 184: interrupt->ChangeINT(this, stat);
1.1 root 185: }
186:
187: // 割り込みアクノリッジ
188: int
189: PEDECDevice::InterruptAcknowledge(int lv)
190: {
1.1.1.4 root 191: uint32 stat = (intmap & intmap_enabled);
1.1 root 192:
193: // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
194: // SPC を優先しておくのでいいだろう。
195: if ((stat & IntmapSPC)) {
196: // XXX PEDEC のベクタに影響されるか?
197: return 0x6c;
198: }
199:
200: if ((stat & IntmapFDC)) {
201: return vector + 0;
1.1.1.6 root 202: } else if ((stat & IntmapFDD)) {
203: return vector + 1;
1.1 root 204: } else {
1.1.1.5 root 205: VMPANIC("Unknown interrupt acknowledge");
1.1 root 206: }
207: }
1.1.1.4 root 208:
209: // デバイスから Intmap 値を引く
210: uint32
211: PEDECDevice::GetIntmap(Device *source) const
212: {
1.1.1.7 ! root 213: if (__predict_true(source == spc)) {
1.1.1.4 root 214: return IntmapSPC;
215: }
1.1.1.7 ! root 216: if (__predict_true(source == fdc)) {
1.1.1.4 root 217: return IntmapFDC;
218: }
1.1.1.6 root 219: if (dynamic_cast<FDDDevice*>(source)) {
220: return IntmapFDD;
221: }
1.1.1.5 root 222: VMPANIC("Unsupported interrupt device");
1.1.1.4 root 223: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.