|
|
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"
1.1.1.6 root 15: #include "m88200.h"
1.1.1.9 ! root 16: #include "mainapp.h"
1.1 root 17:
18: // コンストラクタ
19: CMMUDevice::CMMUDevice()
1.1.1.6 root 20: : inherited(OBJ_CMMUIO)
1.1 root 21: {
22: }
23:
24: // デストラクタ
25: CMMUDevice::~CMMUDevice()
26: {
27: }
28:
1.1.1.6 root 29: // 初期化
1.1 root 30: bool
31: CMMUDevice::Init()
32: {
1.1.1.6 root 33: if (inherited::Init() == false) {
34: return false;
35: }
36:
1.1 root 37: // CMMU をポイントしておく
1.1.1.6 root 38: for (int i = 0; i < cmmus.size(); i++) {
39: cmmus[i] = gMainApp.FindObject<m88200>(OBJ_M88200(i));
40: }
1.1 root 41:
42: return true;
43: }
44:
45: // アドレスデコーダ
46: /*static*/ inline uint32
47: CMMUDevice::Decoder(uint32 addr)
48: {
49: uint32 offset = addr & 0xfff;
50:
51: // BWP* の A5 はデコードされてない
52: if (0x420 <= offset && offset < 0x440) {
53: offset &= ~0x20;
54: }
55: // CDP*,CTP* の A4,A5 はデコードされていない
56: if (0x800 <= offset && offset < 0x880) {
57: offset &= ~0x30;
58: }
59:
60: return offset;
61: }
62:
1.1.1.7 root 63: busdata
1.1.1.8 root 64: CMMUDevice::Read(busaddr addr)
1.1 root 65: {
1.1.1.8 root 66: busdata data;
1.1 root 67:
1.1.1.8 root 68: uint32 paddr = addr.Addr();
69: uint32 id = (paddr >> 12) & 0xff;
1.1 root 70: m88200 *cmmu = GetCMMU(id);
71: if (cmmu == NULL) {
1.1.1.8 root 72: putlog(3, "Read not-equipped CMMU[%u] $%08x", id, paddr);
1.1 root 73: return 0xffffffff;
74: }
75:
1.1.1.8 root 76: uint32 offset = Decoder(paddr);
1.1 root 77: switch (offset) {
78: case IDR:
79: data = cmmu->GetIDR();
1.1.1.8 root 80: cmmu->putlogf(2, lstr("IDR -> $%08x", data.Data()));
1.1.1.7 root 81: break;
1.1 root 82:
83: case SCR:
84: data = cmmu->GetSCR();
1.1.1.8 root 85: cmmu->putlogf(2, lstr("SCR -> $%08x", data.Data()));
1.1.1.7 root 86: break;
1.1 root 87:
88: case SSR:
89: data = cmmu->GetSSR();
1.1.1.8 root 90: cmmu->putlogf(2, lstr("SSR -> $%08x", data.Data()));
1.1.1.7 root 91: break;
1.1 root 92:
93: case SAR:
94: data = cmmu->GetSAR();
1.1.1.8 root 95: cmmu->putlogf(2, lstr("SAR -> $%08x", data.Data()));
1.1.1.7 root 96: break;
1.1 root 97:
98: case SCTR:
99: data = cmmu->GetSCTR();
1.1.1.8 root 100: cmmu->putlogf(2, lstr("SCTR -> $%08x", data.Data()));
1.1.1.7 root 101: break;
1.1 root 102:
103: case PFSR:
104: data = cmmu->GetPFSR();
1.1.1.8 root 105: cmmu->putlogf(2, lstr("PFSR -> $%08x", data.Data()));
1.1.1.7 root 106: break;
1.1 root 107:
108: case PFAR:
109: data = cmmu->GetPFAR();
1.1.1.8 root 110: cmmu->putlogf(2, lstr("PFAR -> $%08x", data.Data()));
1.1.1.7 root 111: break;
1.1 root 112:
113: case SAPR:
114: data = cmmu->GetSAPR();
1.1.1.8 root 115: cmmu->putlogf(2, lstr("SAPR -> $%08x", data.Data()));
1.1.1.7 root 116: break;
1.1 root 117:
118: case UAPR:
119: data = cmmu->GetUAPR();
1.1.1.8 root 120: cmmu->putlogf(2, lstr("UAPR -> $%08x", data.Data()));
1.1.1.7 root 121: break;
1.1 root 122:
123: case BWP0 ... BWP7:
124: // BWP は書き込み専用 (何が読めるだろうか)
1.1.1.7 root 125: data = 0xffffffff;
1.1 root 126: break;
127:
128: case CSSP:
129: data = cmmu->GetCSSP();
1.1.1.8 root 130: cmmu->putlogf(2, lstr("CSSP -> $%08x", data.Data()));
1.1.1.7 root 131: break;
1.1 root 132:
1.1.1.7 root 133: case CDP0 ... CDP3:
134: case CTP0 ... CTP3:
1.1 root 135: default:
1.1.1.8 root 136: putlog(0, "Read $%08x (NOT IMPLEMENTED)", paddr);
1.1.1.7 root 137: data = 0xffffffff;
1.1 root 138: }
1.1.1.7 root 139:
140: // XXX wait?
1.1.1.8 root 141: data |= BusData::Size4;
142: return data;
1.1 root 143: }
144:
1.1.1.7 root 145: busdata
1.1.1.8 root 146: CMMUDevice::Write(busaddr addr, uint32 data)
1.1 root 147: {
1.1.1.8 root 148: uint32 paddr = addr.Addr();
1.1 root 149:
1.1.1.8 root 150: uint32 id = (paddr >> 12) & 0xff;
1.1 root 151: m88200 *cmmu = GetCMMU(id);
152: if (cmmu == NULL) {
1.1.1.8 root 153: putlog(3, "Write not-equipped CMMU[%u] $%08x <- $%08x",
154: id, paddr, data);
1.1 root 155: return 0;
156: }
157:
1.1.1.8 root 158: // 普通はロングワードアクセスしかしないはず。
159: // m88k 専用なのでミスアラインアクセスは起きない。
160: // 88200 p5-27
161: uint32 size = addr.GetSize();
162: if (size == 4) {
163: // nop
164: } else {
165: if (size == 1) {
166: data |= data << 8;
167: }
168: data |= data << 16;
169: }
170:
171: uint32 offset = Decoder(paddr);
1.1 root 172: uint n;
173: switch (offset) {
174: case IDR:
175: {
176: uint32 newid = data >> 24;
177: if (id != newid) {
1.1.1.6 root 178: // 後から ID を変更するのはサポートしない。というか実際無理では。
179: cmmu->putlogf(0, lstr(
180: "IDR <- $%08x (change ID $%02x to $%02x; NOT SUPPORTED)",
181: data, id, newid));
1.1 root 182: } else {
1.1.1.5 root 183: cmmu->putlogf(2, lstr("IDR <- $%08x", data));
1.1 root 184: }
1.1.1.7 root 185: break;
1.1 root 186: }
187:
188: case SCR:
189: cmmu->SetSCR(data);
1.1.1.7 root 190: break;
1.1 root 191:
192: case SSR:
1.1.1.2 root 193: cmmu->putlogf(1, lstr("SSR <- $%08x", data));
1.1 root 194: cmmu->SetSSR(data);
1.1.1.7 root 195: break;
1.1 root 196:
197: case SAR:
1.1.1.2 root 198: cmmu->putlogf(2, lstr("SAR <- $%08x", data));
1.1 root 199: cmmu->SetSAR(data);
1.1.1.7 root 200: break;
1.1 root 201:
202: case SCTR:
203: cmmu->SetSCTR(data);
1.1.1.7 root 204: break;
1.1 root 205:
206: case PFSR:
207: cmmu->SetPFSR(data);
1.1.1.7 root 208: break;
1.1 root 209:
210: case PFAR:
211: cmmu->SetPFAR(data);
1.1.1.7 root 212: break;
1.1 root 213:
214: case SAPR:
215: cmmu->SetSAPR(data);
1.1.1.7 root 216: break;
1.1 root 217:
218: case UAPR:
219: cmmu->SetUAPR(data);
1.1.1.7 root 220: break;
1.1 root 221:
222: case BWP0 ... BWP7:
223: n = (offset - BWP0) / 4;
224: assert(n < 8);
1.1.1.4 root 225: cmmu->SetBWP(n, data);
1.1 root 226: break;
227:
228: case CSSP:
229: cmmu->SetCSSP(data);
1.1.1.7 root 230: break;
1.1 root 231:
1.1.1.7 root 232: case CDP0 ... CDP3:
233: case CTP0 ... CTP3:
1.1 root 234: default:
1.1.1.8 root 235: putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", paddr, data);
1.1.1.7 root 236: VMPANIC("not impl");
1.1 root 237: break;
238: }
1.1.1.7 root 239:
240: // wait?
1.1.1.8 root 241: busdata r = BusData::Size4;
242: return r;
1.1 root 243: }
244:
1.1.1.8 root 245: // Peek1() の下請け。ロングワードで処理して後でバイトに分割するほうが楽。
1.1 root 246: uint32
1.1.1.8 root 247: CMMUDevice::Peek4(uint32 addr) const
1.1 root 248: {
249: uint32 id = (addr >> 12) & 0xff;
250:
251: m88200 *cmmu = GetCMMU(id);
252: if (cmmu == NULL) {
253: return 0xffffffff;
254: }
255:
256: uint32 offset = Decoder(addr);
257: switch (offset) {
258: case IDR:
259: return cmmu->GetIDR();
260:
261: case SCR:
262: return cmmu->GetSCR();
263:
264: case SSR:
265: return cmmu->GetSSR();
266:
267: case SAR:
268: return cmmu->GetSAR();
269:
270: case SCTR:
271: return cmmu->GetSCTR();
272:
273: case PFSR:
274: return cmmu->GetPFSR();
275:
276: case PFAR:
277: return cmmu->GetPFAR();
278:
279: case SAPR:
280: return cmmu->GetSAPR();
281:
282: case UAPR:
283: return cmmu->GetUAPR();
284:
285: case BWP0 ... BWP7:
286: return 0xffffffff;
287:
288: case CDP0 ... CDP3:
289: case CTP0 ... CTP3:
290: break;
291:
292: case CSSP:
293: return cmmu->GetCSSP();
294:
295: default:
296: break;
297: }
298: return 0xffffffff;
299: }
300:
1.1.1.7 root 301: busdata
1.1.1.8 root 302: CMMUDevice::Peek1(uint32 addr)
1.1 root 303: {
1.1.1.8 root 304: uint32 data = Peek4(addr & ~3U);
1.1 root 305: switch (addr & 3) {
306: case 0:
307: return data >> 24;
308: case 1:
309: return (data >> 16) & 0xff;
310: case 2:
311: return (data >> 8) & 0xff;
312: case 3:
313: return data & 0xff;
1.1.1.6 root 314: default:
315: return 0xff;
1.1 root 316: }
317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.