|
|
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 が確定したらそっちのデバイスログから出力する。
13: // CMMU が確定しない場合はこのデバイスのログを使う。
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();
75: cmmu->putlog(2, "IDR -> $%08x", data);
76: return data;
77:
78: case SCR:
79: data = cmmu->GetSCR();
80: cmmu->putlog(2, "SCR -> $%08x", data);
81: return data;
82:
83: case SSR:
84: data = cmmu->GetSSR();
85: cmmu->putlog(2, "SSR -> $%08x", data);
86: return data;
87:
88: case SAR:
89: data = cmmu->GetSAR();
90: cmmu->putlog(2, "SAR -> $%08x", data);
91: return data;
92:
93: case SCTR:
94: data = cmmu->GetSCTR();
95: cmmu->putlog(2, "SCTR -> $%08x", data);
96: return data;
97:
98: case PFSR:
99: data = cmmu->GetPFSR();
100: cmmu->putlog(2, "PFSR -> $%08x", data);
101: return data;
102:
103: case PFAR:
104: data = cmmu->GetPFAR();
105: cmmu->putlog(2, "PFAR -> $%08x", data);
106: return data;
107:
108: case SAPR:
109: data = cmmu->GetSAPR();
110: cmmu->putlog(2, "SAPR -> $%08x", data);
111: return data;
112:
113: case UAPR:
114: data = cmmu->GetUAPR();
115: cmmu->putlog(2, "UAPR -> $%08x", data);
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();
128: cmmu->putlog(2, "CSSP -> $%08x", data);
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) {
156: cmmu->putlog(1, "ID 更新 $%02x", newid);
157: cmmu->SetID(newid);
158: } else {
159: cmmu->putlog(2, "IDR 書き込み(ID変更なし) <- $%08x", data);
160: }
161: return 0;
162: }
163:
164: case SCR:
165: cmmu->SetSCR(data);
166: return 0;
167:
168: case SSR:
169: cmmu->putlog(1, "SSR <- $%08x", data);
170: cmmu->SetSSR(data);
171: return 0;
172:
173: case SAR:
174: cmmu->putlog(2, "SAR <- $%08x", data);
175: cmmu->SetSAR(data);
176: return 0;
177:
178: case SCTR:
179: cmmu->SetSCTR(data);
180: return 0;
181:
182: case PFSR:
183: cmmu->SetPFSR(data);
184: return 0;
185:
186: case PFAR:
187: cmmu->SetPFAR(data);
188: return 0;
189:
190: case SAPR:
191: cmmu->SetSAPR(data);
192: return 0;
193:
194: case UAPR:
195: cmmu->SetUAPR(data);
196: return 0;
197:
198: case BWP0 ... BWP7:
199: n = (offset - BWP0) / 4;
200: assert(n < 8);
201: cmmu->SetBATC(n, data);
202: return 0;
203:
204: case CDP0 ... CDP3:
205: case CTP0 ... CTP3:
206: break;
207:
208: case CSSP:
209: cmmu->SetCSSP(data);
210: return 0;
211:
212: default:
213: break;
214: }
215: putlog(0, "未実装書き込み $%08x <- $%08x", addr, data);
216: PANIC(" ");
217: return 0;
218: }
219:
220: // Peek8() の下請け。32ビットで処理して後でバイトに分割するほうが楽。
221: uint32
222: CMMUDevice::Peek32(uint32 addr) const
223: {
224: uint32 id = (addr >> 12) & 0xff;
225:
226: m88200 *cmmu = GetCMMU(id);
227: if (cmmu == NULL) {
228: return 0xffffffff;
229: }
230:
231: uint32 offset = Decoder(addr);
232: switch (offset) {
233: case IDR:
234: return cmmu->GetIDR();
235:
236: case SCR:
237: return cmmu->GetSCR();
238:
239: case SSR:
240: return cmmu->GetSSR();
241:
242: case SAR:
243: return cmmu->GetSAR();
244:
245: case SCTR:
246: return cmmu->GetSCTR();
247:
248: case PFSR:
249: return cmmu->GetPFSR();
250:
251: case PFAR:
252: return cmmu->GetPFAR();
253:
254: case SAPR:
255: return cmmu->GetSAPR();
256:
257: case UAPR:
258: return cmmu->GetUAPR();
259:
260: case BWP0 ... BWP7:
261: return 0xffffffff;
262:
263: case CDP0 ... CDP3:
264: case CTP0 ... CTP3:
265: break;
266:
267: case CSSP:
268: return cmmu->GetCSSP();
269:
270: default:
271: break;
272: }
273: return 0xffffffff;
274: }
275:
276: uint64
277: CMMUDevice::Peek8(uint32 addr)
278: {
279: uint32 data = Peek32(addr & ~3U);
280: switch (addr & 3) {
281: case 0:
282: return data >> 24;
283: case 1:
284: return (data >> 16) & 0xff;
285: case 2:
286: return (data >> 8) & 0xff;
287: case 3:
288: return data & 0xff;
289: }
290: __unreachable();
291: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.