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