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