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