|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: #include "pedec.h"
8: #include "fdc.h"
9: #include "spc.h"
10:
11: std::unique_ptr<PEDECDevice> gPEDEC;
12:
13: PEDECDevice::PEDECDevice()
1.1.1.3 ! root 14: : inherited("PEDEC")
1.1 root 15: {
16: devaddr = baseaddr;
17: devlen = 0x2000;
18: }
19:
20: PEDECDevice::~PEDECDevice()
21: {
22: }
23:
24: void
25: PEDECDevice::ResetHard()
26: {
27: int_asserted = 0;
28: int_enabled = IntmapSPC;
29: // XXX vector
30: }
31:
32: uint64
1.1.1.2 root 33: PEDECDevice::Read(uint32 offset)
1.1 root 34: {
1.1.1.2 root 35: switch (offset) {
1.1 root 36: case 0: // $E9C001 割り込みステータス
37: return GetStat();
38:
39: case 1: // $E9C003 割り込みベクタ
40: // 書き込み専用
41: return 0xff;
42:
43: default:
44: return 0xff;
45: }
46: }
47:
48: uint64
1.1.1.2 root 49: PEDECDevice::Write(uint32 offset, uint32 data)
1.1 root 50: {
1.1.1.2 root 51: switch (offset) {
1.1 root 52: case 0: // $E9C001 割り込みマスク
53: int_enabled = IntmapSPC;
54: int_enabled |= (data & 0x08) ? IntmapHDD : 0;
55: int_enabled |= (data & 0x04) ? IntmapFDC : 0;
56: int_enabled |= (data & 0x02) ? IntmapFDD : 0;
57: int_enabled |= (data & 0x01) ? IntmapPRT : 0;
58:
59: putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d",
60: ((int_enabled & IntmapHDD) ? 1 : 0),
61: ((int_enabled & IntmapFDC) ? 1 : 0),
62: ((int_enabled & IntmapFDD) ? 1 : 0),
63: ((int_enabled & IntmapPRT) ? 1 : 0));
64: return 0;
65:
66: case 1: // $E9C003 割り込みベクタ
67: vector = data & 0xfc;
68: putlog(1, "割り込みベクタ設定 $%02x", vector);
69: return 0;
70:
71: default:
72: return 0;
73: }
74: }
75:
76: uint64
1.1.1.2 root 77: PEDECDevice::Peek(uint32 offset)
1.1 root 78: {
1.1.1.2 root 79: switch (offset) {
1.1 root 80: case 0:
81: return GetStat();
82:
83: case 1:
84: // 書き込み専用
85: return 0xff;
86:
87: default:
88: return 0xff;
89: }
90: }
91:
92: // 割り込みステータスレジスタの値を取得。
93: // (Peek からも呼ばれるので副作用を持たせてはいけない)
94: uint32
95: PEDECDevice::GetStat() const
96: {
97: uint32 data = 0;
98: data |= (int_asserted & IntmapFDC) ? 0x80 : 0;
99: data |= (int_asserted & IntmapFDD) ? 0x40 : 0;
100: data |= (int_asserted & IntmapPRT) ? 0x20 : 0;
101: data |= (int_asserted & IntmapHDD) ? 0x10 : 0;
102: data |= (int_enabled & IntmapHDD) ? 0x08 : 0;
103: data |= (int_enabled & IntmapFDC) ? 0x04 : 0;
104: data |= (int_enabled & IntmapFDD) ? 0x02 : 0;
105: data |= (int_enabled & IntmapPRT) ? 0x01 : 0;
106: return data;
107: }
108:
109: // 子デバイスが割り込み信号線をアサートした
110: void
111: PEDECDevice::AssertINT(Device *source)
112: {
113: if (__predict_true(source == gSPC.get())) {
114: int_asserted |= IntmapSPC;
115:
116: } else if (__predict_true(source == gFDC.get())) {
117: int_asserted |= IntmapFDC;
118: // ログ表示のためだけ
119: if ((int_enabled & IntmapFDC)) {
120: putlog(1, "FDC からの割り込み要求");
121: } else {
122: putlog(2, "FDC からの割り込み要求(マスク)");
123: }
124:
125: } else {
126: PANIC("Unknown interrupt source");
127: }
128:
129: ChangeInterrupt();
130: }
131:
132: // 子デバイスが割り込み信号線をネゲートした
133: void
134: PEDECDevice::NegateINT(Device *source)
135: {
136: if (__predict_true(source == gSPC.get())) {
137: int_asserted &= ~IntmapSPC;
138: } else if (__predict_true(source == gFDC.get())) {
139: int_asserted &= ~IntmapFDC;
140: } else {
141: PANIC("Unknown interrupt source");
142: }
143:
144: ChangeInterrupt();
145: }
146:
147: // 割り込み信号線の状態を変える
148: void
149: PEDECDevice::ChangeInterrupt()
150: {
151: uint32 stat = (int_asserted & int_enabled);
152: gInterrupt->ChangeINT(this, stat);
153: }
154:
155: // 割り込みアクノリッジ
156: int
157: PEDECDevice::InterruptAcknowledge(int lv)
158: {
159: uint32 stat = (int_asserted & int_enabled);
160:
161: // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので
162: // SPC を優先しておくのでいいだろう。
163: if ((stat & IntmapSPC)) {
164: // XXX PEDEC のベクタに影響されるか?
165: return 0x6c;
166: }
167:
168: if ((stat & IntmapFDC)) {
169: return vector + 0;
170: } else {
171: PANIC("Unknown interrupt acknowledge");
172: }
173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.