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