|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2020 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // M88200 CMMU の I/O デバイス部分 ! 8: ! 9: #include "cmmu.h" ! 10: #include "mpu88xx0.h" ! 11: ! 12: // CMMU が確定したらそっちのデバイスログから出力する。 ! 13: // CMMU が確定しない場合はこのデバイスのログを使う。 ! 14: ! 15: std::unique_ptr<CMMUDevice> gCMMU; ! 16: ! 17: // コンストラクタ ! 18: CMMUDevice::CMMUDevice() ! 19: { ! 20: // m88200 側の logname が "cmmu7" とかなので、こっちを "cmmu" で ! 21: // 受け付けてしまうのは紛らわしそうなので。 ! 22: logname = "cmmudev"; ! 23: devname = "CMMU"; ! 24: } ! 25: ! 26: // デストラクタ ! 27: CMMUDevice::~CMMUDevice() ! 28: { ! 29: } ! 30: ! 31: bool ! 32: CMMUDevice::Init() ! 33: { ! 34: // CMMU をポイントしておく ! 35: cmmus[7] = &gMPU88xx0->GetCPU()->cmmu[0]; ! 36: cmmus[6] = &gMPU88xx0->GetCPU()->cmmu[1]; ! 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: ! 59: uint64 ! 60: CMMUDevice::Read32(uint32 addr) ! 61: { ! 62: uint32 id = (addr >> 12) & 0xff; ! 63: ! 64: m88200 *cmmu = GetCMMU(id); ! 65: if (cmmu == NULL) { ! 66: putlog(3, "未搭載 CMMU[%d] 読み込み $%08x", id, addr); ! 67: return 0xffffffff; ! 68: } ! 69: ! 70: uint32 offset = Decoder(addr); ! 71: uint32 data; ! 72: switch (offset) { ! 73: case IDR: ! 74: data = cmmu->GetIDR(); ! 75: cmmu->putlog(2, "IDR -> $%08x", data); ! 76: return data; ! 77: ! 78: case SCR: ! 79: data = cmmu->GetSCR(); ! 80: cmmu->putlog(2, "SCR -> $%08x", data); ! 81: return data; ! 82: ! 83: case SSR: ! 84: data = cmmu->GetSSR(); ! 85: cmmu->putlog(2, "SSR -> $%08x", data); ! 86: return data; ! 87: ! 88: case SAR: ! 89: data = cmmu->GetSAR(); ! 90: cmmu->putlog(2, "SAR -> $%08x", data); ! 91: return data; ! 92: ! 93: case SCTR: ! 94: data = cmmu->GetSCTR(); ! 95: cmmu->putlog(2, "SCTR -> $%08x", data); ! 96: return data; ! 97: ! 98: case PFSR: ! 99: data = cmmu->GetPFSR(); ! 100: cmmu->putlog(2, "PFSR -> $%08x", data); ! 101: return data; ! 102: ! 103: case PFAR: ! 104: data = cmmu->GetPFAR(); ! 105: cmmu->putlog(2, "PFAR -> $%08x", data); ! 106: return data; ! 107: ! 108: case SAPR: ! 109: data = cmmu->GetSAPR(); ! 110: cmmu->putlog(2, "SAPR -> $%08x", data); ! 111: return data; ! 112: ! 113: case UAPR: ! 114: data = cmmu->GetUAPR(); ! 115: cmmu->putlog(2, "UAPR -> $%08x", data); ! 116: return data; ! 117: ! 118: case BWP0 ... BWP7: ! 119: // BWP は書き込み専用 (何が読めるだろうか) ! 120: return 0xffffffff; ! 121: ! 122: case CDP0 ... CDP3: ! 123: case CTP0 ... CTP3: ! 124: break; ! 125: ! 126: case CSSP: ! 127: data = cmmu->GetCSSP(); ! 128: cmmu->putlog(2, "CSSP -> $%08x", data); ! 129: return data; ! 130: ! 131: default: ! 132: break; ! 133: } ! 134: putlog(0, "未実装読み込み $%08x", addr); ! 135: return 0xffffffff; ! 136: } ! 137: ! 138: uint64 ! 139: CMMUDevice::Write32(uint32 addr, uint32 data) ! 140: { ! 141: uint32 id = (addr >> 12) & 0xff; ! 142: ! 143: m88200 *cmmu = GetCMMU(id); ! 144: if (cmmu == NULL) { ! 145: putlog(3, "未搭載 CMMU[%d] 書き込み $%08x <- $%08x", id, addr, data); ! 146: return 0; ! 147: } ! 148: ! 149: uint32 offset = Decoder(addr); ! 150: uint n; ! 151: switch (offset) { ! 152: case IDR: ! 153: { ! 154: uint32 newid = data >> 24; ! 155: if (id != newid) { ! 156: cmmu->putlog(1, "ID 更新 $%02x", newid); ! 157: cmmu->SetID(newid); ! 158: } else { ! 159: cmmu->putlog(2, "IDR 書き込み(ID変更なし) <- $%08x", data); ! 160: } ! 161: return 0; ! 162: } ! 163: ! 164: case SCR: ! 165: cmmu->SetSCR(data); ! 166: return 0; ! 167: ! 168: case SSR: ! 169: cmmu->putlog(1, "SSR <- $%08x", data); ! 170: cmmu->SetSSR(data); ! 171: return 0; ! 172: ! 173: case SAR: ! 174: cmmu->putlog(2, "SAR <- $%08x", data); ! 175: cmmu->SetSAR(data); ! 176: return 0; ! 177: ! 178: case SCTR: ! 179: cmmu->SetSCTR(data); ! 180: return 0; ! 181: ! 182: case PFSR: ! 183: cmmu->SetPFSR(data); ! 184: return 0; ! 185: ! 186: case PFAR: ! 187: cmmu->SetPFAR(data); ! 188: return 0; ! 189: ! 190: case SAPR: ! 191: cmmu->SetSAPR(data); ! 192: return 0; ! 193: ! 194: case UAPR: ! 195: cmmu->SetUAPR(data); ! 196: return 0; ! 197: ! 198: case BWP0 ... BWP7: ! 199: n = (offset - BWP0) / 4; ! 200: assert(n < 8); ! 201: cmmu->SetBATC(n, data); ! 202: return 0; ! 203: ! 204: case CDP0 ... CDP3: ! 205: case CTP0 ... CTP3: ! 206: break; ! 207: ! 208: case CSSP: ! 209: cmmu->SetCSSP(data); ! 210: return 0; ! 211: ! 212: default: ! 213: break; ! 214: } ! 215: putlog(0, "未実装書き込み $%08x <- $%08x", addr, data); ! 216: PANIC(" "); ! 217: return 0; ! 218: } ! 219: ! 220: // Peek8() の下請け。32ビットで処理して後でバイトに分割するほうが楽。 ! 221: uint32 ! 222: CMMUDevice::Peek32(uint32 addr) const ! 223: { ! 224: uint32 id = (addr >> 12) & 0xff; ! 225: ! 226: m88200 *cmmu = GetCMMU(id); ! 227: if (cmmu == NULL) { ! 228: return 0xffffffff; ! 229: } ! 230: ! 231: uint32 offset = Decoder(addr); ! 232: switch (offset) { ! 233: case IDR: ! 234: return cmmu->GetIDR(); ! 235: ! 236: case SCR: ! 237: return cmmu->GetSCR(); ! 238: ! 239: case SSR: ! 240: return cmmu->GetSSR(); ! 241: ! 242: case SAR: ! 243: return cmmu->GetSAR(); ! 244: ! 245: case SCTR: ! 246: return cmmu->GetSCTR(); ! 247: ! 248: case PFSR: ! 249: return cmmu->GetPFSR(); ! 250: ! 251: case PFAR: ! 252: return cmmu->GetPFAR(); ! 253: ! 254: case SAPR: ! 255: return cmmu->GetSAPR(); ! 256: ! 257: case UAPR: ! 258: return cmmu->GetUAPR(); ! 259: ! 260: case BWP0 ... BWP7: ! 261: return 0xffffffff; ! 262: ! 263: case CDP0 ... CDP3: ! 264: case CTP0 ... CTP3: ! 265: break; ! 266: ! 267: case CSSP: ! 268: return cmmu->GetCSSP(); ! 269: ! 270: default: ! 271: break; ! 272: } ! 273: return 0xffffffff; ! 274: } ! 275: ! 276: uint64 ! 277: CMMUDevice::Peek8(uint32 addr) ! 278: { ! 279: uint32 data = Peek32(addr & ~3U); ! 280: switch (addr & 3) { ! 281: case 0: ! 282: return data >> 24; ! 283: case 1: ! 284: return (data >> 16) & 0xff; ! 285: case 2: ! 286: return (data >> 8) & 0xff; ! 287: case 3: ! 288: return data & 0xff; ! 289: } ! 290: __unreachable(); ! 291: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.