|
|
1.1 root 1: //
2: // nono
1.1.1.3 ! root 3: // Copyright (C) 2020 nono project
! 4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #include "scc.h"
1.1.1.3 ! root 8: #include "mpu680x0.h"
1.1 root 9:
10: // IODevice
11: // |
12: // v
13: // upd7201Device (uPD7201 と Z8530 の共通部分)
14: // |
15: // +---------+----------+
16: // v v
17: // SIODevice SCCDevice
18: // (LUNA, uPD7201) (X68030, Z8530)
19:
1.1.1.2 root 20: std::unique_ptr<SCCDevice> gSCC;
21:
1.1 root 22: SCCDevice::SCCDevice()
23: {
24: logname = "scc";
25: devname = "SCC";
26: devaddr = baseaddr;
27: devlen = 0x2000;
1.1.1.2 root 28:
29: cr.chan[0].desc = "Serial Port";
30: cr.chan[1].desc = "Mouse";
1.1 root 31: }
32:
33: SCCDevice::~SCCDevice()
34: {
35: }
36:
37: // Z8530 は RD と WR を同時に Low にするとリセットがかかる。
38: // 回路図からは PEDEC から繋がってるという以上のことは分からないけど
39: // 普通に考えればハードリセットでリセットされるよな。
40: void
41: SCCDevice::ResetHard()
42: {
43: Reset();
44: }
45:
46: uint64
1.1.1.3 ! root 47: SCCDevice::Read(uint32 addr)
1.1 root 48: {
1.1.1.3 ! root 49: switch (addr) {
! 50: case 0: // $E98001
1.1 root 51: return ReadCtrl(&cr.chan[1]);
52:
1.1.1.3 ! root 53: case 1: // $E98003
1.1 root 54: // マウス非接続は 0x00 ?
55: putlog(0, "ChB データレジスタ読み込み (未実装)");
56: return 0x00;
57:
1.1.1.3 ! root 58: case 2: // $E98005
1.1 root 59: return ReadCtrl(&cr.chan[0]);
60:
1.1.1.3 ! root 61: case 3: // $E98007
1.1 root 62: putlog(0, "ChA データレジスタ読み込み (未実装)");
1.1.1.2 root 63: return ReadData(&cr.chan[0]);
1.1 root 64: }
1.1.1.3 ! root 65: __unreachable();
1.1 root 66: }
67:
68: uint64
1.1.1.3 ! root 69: SCCDevice::Write(uint32 addr, uint32 data)
1.1 root 70: {
1.1.1.3 ! root 71: switch (addr) {
! 72: case 0: // $E98001
1.1 root 73: WriteCtrl(&cr.chan[1], data);
74: return 0;
75:
1.1.1.3 ! root 76: case 1: // $E98003
1.1 root 77: WriteData(&cr.chan[1], data);
78: return 0;
79:
1.1.1.3 ! root 80: case 2: // $E98005
1.1 root 81: WriteCtrl(&cr.chan[0], data);
82: return 0;
83:
1.1.1.3 ! root 84: case 3: // $E98007
1.1 root 85: WriteData(&cr.chan[0], data);
86: return 0;
87: }
1.1.1.3 ! root 88: __unreachable();
1.1 root 89: }
90:
91: uint64
1.1.1.3 ! root 92: SCCDevice::Peek(uint32 addr)
1.1 root 93: {
1.1.1.3 ! root 94: switch (addr) {
! 95: case 0: // $E98001
1.1.1.2 root 96: return PeekCtrl(&cr.chan[1]);
97:
1.1.1.3 ! root 98: case 1: // $E98003
1.1.1.2 root 99: // マウス非接続は 0x00 ?
100: return 0x00;
101:
1.1.1.3 ! root 102: case 2: // $E98005
1.1.1.2 root 103: return PeekCtrl(&cr.chan[0]);
104:
1.1.1.3 ! root 105: case 3: // $E98007
1.1.1.2 root 106: return PeekData(&cr.chan[0]);
107: }
1.1.1.3 ! root 108: __unreachable();
1.1 root 109: }
110:
111: // Z8530 制御ポート読み込み
112: uint8
113: SCCDevice::ReadCtrl(struct SIO::channel *chan)
114: {
115: return inherited::ReadCtrl(chan);
116: }
117:
118: // Z8530 制御ポート書き込み
119: void
120: SCCDevice::WriteCtrl(struct SIO::channel *chan, uint32 data)
121: {
122: switch (chan->ptr) {
123: case 0: // WR0
124: chan->cr0 = data;
125:
126: switch ((chan->cr0 & SIO::WR0_CMD) >> 3) {
127: case 0:
128: case 1:
129: // コマンド 0、1 がレジスタ切り替え
130: chan->ptr = chan->cr0 & SIO::WR0_PTR;
131: putlog(3, "WR0%s <- $%02x (ptr=%d)", chan->name, data, chan->ptr);
132: break;
133:
134: case 2: // Reset Ext/Status Interrupts
135: putlog(0, "WR0 Reset Ext/Status Interrupts 未実装");
136: break;
137: case 3: // Send Abort
138: putlog(0, "WR0 Send Abort 未実装");
139: break;
140: case 4: // Enable Int on Next Rx Character
141: putlog(0, "WR0 Enable Int on Next Rx Character 未実装");
142: break;
143: case 5: // Reset Tx Int Pending
144: putlog(0, "WR0 Reset Tx Int Pending 未実装");
145: break;
146: case 6: // Error Reset
147: putlog(0, "WR0 Error Reset 未実装");
148: break;
149: case 7: // Reset Highest IUS
150: putlog(0, "WR0 Reset Highest IUS");
151: break;
152: }
153: break;
154:
155: case 2: // WR2
156: // Z8530 の WR2 は A/B 共通でベクタ設定
157: putlog(2, "WR2 <- $%02x ベクタ設定", data);
158: cr.vector = data;
159: // アクセス後は WR0 へ戻す
160: chan->ptr = 0;
161: break;
162:
163: case 1: // WR1
164: case 3:
165: case 4:
166: case 5:
167: case 6:
168: case 7:
169: inherited::WriteCtrl(chan, data);
170: break;
171:
172: case 8: // WR8
173: WriteData(chan, data);
174: // アクセス後は WR0 へ戻す
175: chan->ptr = 0;
176: break;
177:
178: case 9: // WR9
179: putlog(2, "WR%d%s <- $%02x", chan->ptr, chan->name, data);
180: switch ((data & 0xc0) >> 6) {
181: case 0: // No Reset
182: break;
183: case 1: // Channel Reset A
184: ResetChannel(&cr.chan[0]);
185: break;
186: case 2: // Channel Reset B
187: ResetChannel(&cr.chan[1]);
188: break;
189: case 3: // Force Hardware Reset
190: Reset();
191: break;
192: default:
193: __unreachable();
194: }
195: // アクセス後は WR0 へ戻す
196: chan->ptr = 0;
197: break;
198:
199: case 11: // WR11
200: putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
201: chan->wr11 = data;
202: // アクセス後は WR0 へ戻す
203: chan->ptr = 0;
204: break;
205:
206: case 12: // WR12
207: chan->tc = (chan->tc & 0xff00) | data;
208: putlog(2, "WR%d%s TC(L)=%04x", chan->ptr, chan->name, chan->tc);
209: // アクセス後は WR0 へ戻す
210: chan->ptr = 0;
211: break;
212:
213: case 13: // WR13
214: chan->tc = (chan->tc & 0x00ff) | (data << 8);
215: putlog(2, "WR%d%s TC(H)=%04x", chan->ptr, chan->name, chan->tc);
216: // アクセス後は WR0 へ戻す
217: chan->ptr = 0;
218: break;
219:
220: case 14: // WR14
221: putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
222: chan->wr14 = data;
223: // アクセス後は WR0 へ戻す
224: chan->ptr = 0;
225: break;
226:
227: case 15: // WR15
228: putlog(2, "WR%d%s <- $%02x (未実装)", chan->ptr, chan->name, data);
229: chan->wr15 = data;
230: // アクセス後は WR0 へ戻す
231: chan->ptr = 0;
232: break;
233:
234: default:
235: PANIC("未実装レジスタ書き込み WR%d%s <- $%02x",
236: chan->ptr, chan->name, data);
237: break;
238: }
239: }
240:
241: // 割り込みを上げる
242: void
243: SCCDevice::Interrupt()
244: {
245: putlog(0, "割り込み(未実装)");
1.1.1.3 ! root 246: gMPU680x0->Interrupt(this, 5, 0x50/*XXX*/);
1.1 root 247: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.