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