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