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