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