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