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