|
|
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) {
1.1.1.5 ! root 67: putlog(3, "Read not-equipped CMMU[%d] $%08x", id, addr);
1.1 root 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: }
1.1.1.5 ! root 135: putlog(0, "Read $%08x (NOT IMPLEMENTED)", addr);
1.1 root 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) {
1.1.1.5 ! root 146: putlog(3, "Write not-equipped CMMU[%d] $%08x <- $%08x", id, addr, data);
1.1 root 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.5 ! root 157: cmmu->putlogf(1, lstr("IDR <- $%08x (set ID $%02x)", data, newid));
1.1 root 158: cmmu->SetID(newid);
159: } else {
1.1.1.5 ! root 160: cmmu->putlogf(2, lstr("IDR <- $%08x", 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);
1.1.1.4 root 202: cmmu->SetBWP(n, data);
1.1 root 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: }
1.1.1.5 ! root 216: putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", addr, data);
1.1.1.4 root 217: VMPANIC("not impl");
1.1 root 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.