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