|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: // M88200 CMMU の I/O デバイス部分
8:
9: #include "cmmu.h"
10: #include "mpu88xx0.h"
11:
12: // CMMU が確定しない場合はこのデバイスのログを使う。
1.1.1.2 root 13: // CMMU が確定したらそっちのデバイスログから出力する。
1.1 root 14:
15: std::unique_ptr<CMMUDevice> gCMMU;
16:
17: // コンストラクタ
18: CMMUDevice::CMMUDevice()
1.1.1.3 ! root 19: : inherited("CMMUIOSpace")
1.1 root 20: {
21: }
22:
23: // デストラクタ
24: CMMUDevice::~CMMUDevice()
25: {
26: }
27:
28: bool
29: CMMUDevice::Init()
30: {
31: // CMMU をポイントしておく
32: cmmus[7] = &gMPU88xx0->GetCPU()->cmmu[0];
33: cmmus[6] = &gMPU88xx0->GetCPU()->cmmu[1];
34:
35: return true;
36: }
37:
38: // アドレスデコーダ
39: /*static*/ inline uint32
40: CMMUDevice::Decoder(uint32 addr)
41: {
42: uint32 offset = addr & 0xfff;
43:
44: // BWP* の A5 はデコードされてない
45: if (0x420 <= offset && offset < 0x440) {
46: offset &= ~0x20;
47: }
48: // CDP*,CTP* の A4,A5 はデコードされていない
49: if (0x800 <= offset && offset < 0x880) {
50: offset &= ~0x30;
51: }
52:
53: return offset;
54: }
55:
56: uint64
57: CMMUDevice::Read32(uint32 addr)
58: {
59: uint32 id = (addr >> 12) & 0xff;
60:
61: m88200 *cmmu = GetCMMU(id);
62: if (cmmu == NULL) {
63: putlog(3, "未搭載 CMMU[%d] 読み込み $%08x", id, addr);
64: return 0xffffffff;
65: }
66:
67: uint32 offset = Decoder(addr);
68: uint32 data;
69: switch (offset) {
70: case IDR:
71: data = cmmu->GetIDR();
1.1.1.2 root 72: cmmu->putlogf(2, lstr("IDR -> $%08x", data));
1.1 root 73: return data;
74:
75: case SCR:
76: data = cmmu->GetSCR();
1.1.1.2 root 77: cmmu->putlogf(2, lstr("SCR -> $%08x", data));
1.1 root 78: return data;
79:
80: case SSR:
81: data = cmmu->GetSSR();
1.1.1.2 root 82: cmmu->putlogf(2, lstr("SSR -> $%08x", data));
1.1 root 83: return data;
84:
85: case SAR:
86: data = cmmu->GetSAR();
1.1.1.2 root 87: cmmu->putlogf(2, lstr("SAR -> $%08x", data));
1.1 root 88: return data;
89:
90: case SCTR:
91: data = cmmu->GetSCTR();
1.1.1.2 root 92: cmmu->putlogf(2, lstr("SCTR -> $%08x", data));
1.1 root 93: return data;
94:
95: case PFSR:
96: data = cmmu->GetPFSR();
1.1.1.2 root 97: cmmu->putlogf(2, lstr("PFSR -> $%08x", data));
1.1 root 98: return data;
99:
100: case PFAR:
101: data = cmmu->GetPFAR();
1.1.1.2 root 102: cmmu->putlogf(2, lstr("PFAR -> $%08x", data));
1.1 root 103: return data;
104:
105: case SAPR:
106: data = cmmu->GetSAPR();
1.1.1.2 root 107: cmmu->putlogf(2, lstr("SAPR -> $%08x", data));
1.1 root 108: return data;
109:
110: case UAPR:
111: data = cmmu->GetUAPR();
1.1.1.2 root 112: cmmu->putlogf(2, lstr("UAPR -> $%08x", data));
1.1 root 113: return data;
114:
115: case BWP0 ... BWP7:
116: // BWP は書き込み専用 (何が読めるだろうか)
117: return 0xffffffff;
118:
119: case CDP0 ... CDP3:
120: case CTP0 ... CTP3:
121: break;
122:
123: case CSSP:
124: data = cmmu->GetCSSP();
1.1.1.2 root 125: cmmu->putlogf(2, lstr("CSSP -> $%08x", data));
1.1 root 126: return data;
127:
128: default:
129: break;
130: }
131: putlog(0, "未実装読み込み $%08x", addr);
132: return 0xffffffff;
133: }
134:
135: uint64
136: CMMUDevice::Write32(uint32 addr, uint32 data)
137: {
138: uint32 id = (addr >> 12) & 0xff;
139:
140: m88200 *cmmu = GetCMMU(id);
141: if (cmmu == NULL) {
142: putlog(3, "未搭載 CMMU[%d] 書き込み $%08x <- $%08x", id, addr, data);
143: return 0;
144: }
145:
146: uint32 offset = Decoder(addr);
147: uint n;
148: switch (offset) {
149: case IDR:
150: {
151: uint32 newid = data >> 24;
152: if (id != newid) {
1.1.1.2 root 153: cmmu->putlogf(1, lstr("ID 更新 $%02x", newid));
1.1 root 154: cmmu->SetID(newid);
155: } else {
1.1.1.2 root 156: cmmu->putlogf(2, lstr("IDR 書き込み(ID変更なし) <- $%08x",
157: data));
1.1 root 158: }
159: return 0;
160: }
161:
162: case SCR:
163: cmmu->SetSCR(data);
164: return 0;
165:
166: case SSR:
1.1.1.2 root 167: cmmu->putlogf(1, lstr("SSR <- $%08x", data));
1.1 root 168: cmmu->SetSSR(data);
169: return 0;
170:
171: case SAR:
1.1.1.2 root 172: cmmu->putlogf(2, lstr("SAR <- $%08x", data));
1.1 root 173: cmmu->SetSAR(data);
174: return 0;
175:
176: case SCTR:
177: cmmu->SetSCTR(data);
178: return 0;
179:
180: case PFSR:
181: cmmu->SetPFSR(data);
182: return 0;
183:
184: case PFAR:
185: cmmu->SetPFAR(data);
186: return 0;
187:
188: case SAPR:
189: cmmu->SetSAPR(data);
190: return 0;
191:
192: case UAPR:
193: cmmu->SetUAPR(data);
194: return 0;
195:
196: case BWP0 ... BWP7:
197: n = (offset - BWP0) / 4;
198: assert(n < 8);
199: cmmu->SetBATC(n, data);
200: return 0;
201:
202: case CDP0 ... CDP3:
203: case CTP0 ... CTP3:
204: break;
205:
206: case CSSP:
207: cmmu->SetCSSP(data);
208: return 0;
209:
210: default:
211: break;
212: }
213: putlog(0, "未実装書き込み $%08x <- $%08x", addr, data);
214: PANIC(" ");
215: return 0;
216: }
217:
218: // Peek8() の下請け。32ビットで処理して後でバイトに分割するほうが楽。
219: uint32
220: CMMUDevice::Peek32(uint32 addr) const
221: {
222: uint32 id = (addr >> 12) & 0xff;
223:
224: m88200 *cmmu = GetCMMU(id);
225: if (cmmu == NULL) {
226: return 0xffffffff;
227: }
228:
229: uint32 offset = Decoder(addr);
230: switch (offset) {
231: case IDR:
232: return cmmu->GetIDR();
233:
234: case SCR:
235: return cmmu->GetSCR();
236:
237: case SSR:
238: return cmmu->GetSSR();
239:
240: case SAR:
241: return cmmu->GetSAR();
242:
243: case SCTR:
244: return cmmu->GetSCTR();
245:
246: case PFSR:
247: return cmmu->GetPFSR();
248:
249: case PFAR:
250: return cmmu->GetPFAR();
251:
252: case SAPR:
253: return cmmu->GetSAPR();
254:
255: case UAPR:
256: return cmmu->GetUAPR();
257:
258: case BWP0 ... BWP7:
259: return 0xffffffff;
260:
261: case CDP0 ... CDP3:
262: case CTP0 ... CTP3:
263: break;
264:
265: case CSSP:
266: return cmmu->GetCSSP();
267:
268: default:
269: break;
270: }
271: return 0xffffffff;
272: }
273:
274: uint64
275: CMMUDevice::Peek8(uint32 addr)
276: {
277: uint32 data = Peek32(addr & ~3U);
278: switch (addr & 3) {
279: case 0:
280: return data >> 24;
281: case 1:
282: return (data >> 16) & 0xff;
283: case 2:
284: return (data >> 8) & 0xff;
285: case 3:
286: return data & 0xff;
287: }
288: __unreachable();
289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.