|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2022 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: // ! 8: // XP プロセッサの物理バス ! 9: // ! 10: ! 11: // 00000H +-------------------+ ! 12: // | 3Port RAM (128KB) | ! 13: // 20000H +-------------------+ ! 14: // | PROM (32KB) | ソケットが空のようだ ! 15: // 28000H +-------------------+ ! 16: // | 3Port RAM (32KB) | ! 17: // 30000H +-------------------+ ! 18: // | | ! 19: // : 無効 ! 20: // | | ! 21: // FFE00H +-------------------+ ! 22: // | 内蔵 RAM (512B) | (実際の位置は I/O で決まる) ! 23: // FFFFFH +-------------------+ ! 24: // ! 25: // 3Port RAM (128KB) のほうは vm_luna で確保されている subram、 ! 26: // 3Port RAM (32KB) のほうはこちらで確保する subram2。 ! 27: // 内蔵 RAM は XPBusDevice の internal_ram[]。 ! 28: ! 29: #include "xpbus.h" ! 30: #include "subram.h" ! 31: ! 32: // コンストラクタ ! 33: XPbusDevice::XPbusDevice() ! 34: : inherited(OBJ_XPBUS) ! 35: { ! 36: pSubRAM2.reset(new SubRAM2Device(32)); ! 37: pXPRAM.reset(new XPRAMDevice()); ! 38: } ! 39: ! 40: // デストラクタ ! 41: XPbusDevice::~XPbusDevice() ! 42: { ! 43: } ! 44: ! 45: // 初期化 ! 46: bool ! 47: XPbusDevice::Init() ! 48: { ! 49: if (inherited::Init() == false) { ! 50: return false; ! 51: } ! 52: ! 53: nopio = GetNopIODevice(); ! 54: subram = GetSubRAMDevice(); ! 55: return true; ! 56: } ! 57: ! 58: void ! 59: XPbusDevice::ResetHard(bool poweron) ! 60: { ! 61: // RMCR のリセットは XP 側からされるのでここでは何もしない ! 62: } ! 63: ! 64: inline IODevice * ! 65: XPbusDevice::SearchDevice(uint32 addr) const ! 66: { ! 67: // まず内蔵 512 バイトRAM (位置は設定で可変) ! 68: if (__predict_true((addr & 0xffe00) == ram_addr)) { ! 69: return pXPRAM.get(); ! 70: } ! 71: ! 72: if (__predict_true(addr < 0x20000)) { // 00000H-20000H: 3Port RAM (128KB) ! 73: return subram; ! 74: } ! 75: if (__predict_false(addr < 0x28000)) { // 20000H-28000H: PROM 領域 (32KB) ! 76: return nopio; ! 77: } ! 78: if (__predict_true(addr < 0x30000)) { // 28000H-30000H: 非共有 RAM (32KB) ! 79: return pSubRAM2.get(); ! 80: } ! 81: // 30000H 以降は空き。 ! 82: // アクセス特性が NopIO かどうかは未調査。 ! 83: return nopio; ! 84: } ! 85: ! 86: uint64 ! 87: XPbusDevice::Read8(uint32 addr) ! 88: { ! 89: addr &= 0x000fffff; ! 90: IODevice *d = SearchDevice(addr); ! 91: return d->Read8(addr); ! 92: } ! 93: ! 94: uint64 ! 95: XPbusDevice::Read16(uint32 addr) ! 96: { ! 97: addr &= 0x000fffff; ! 98: IODevice *d = SearchDevice(addr); ! 99: return d->Read16(addr); ! 100: } ! 101: ! 102: uint64 ! 103: XPbusDevice::Read32(uint32 addr) ! 104: { ! 105: addr &= 0x000fffff; ! 106: IODevice *d = SearchDevice(addr); ! 107: return d->Read32(addr); ! 108: } ! 109: ! 110: uint64 ! 111: XPbusDevice::Write8(uint32 addr, uint32 data) ! 112: { ! 113: addr &= 0x000fffff; ! 114: IODevice *d = SearchDevice(addr); ! 115: return d->Write8(addr, data); ! 116: } ! 117: ! 118: uint64 ! 119: XPbusDevice::Write16(uint32 addr, uint32 data) ! 120: { ! 121: addr &= 0x000fffff; ! 122: IODevice *d = SearchDevice(addr); ! 123: return d->Write16(addr, data); ! 124: } ! 125: ! 126: uint64 ! 127: XPbusDevice::Write32(uint32 addr, uint32 data) ! 128: { ! 129: addr &= 0x000fffff; ! 130: IODevice *d = SearchDevice(addr); ! 131: return d->Write32(addr, data); ! 132: } ! 133: ! 134: uint64 ! 135: XPbusDevice::Peek8(uint32 addr) ! 136: { ! 137: addr &= 0x000fffff; ! 138: IODevice *d = SearchDevice(addr); ! 139: return d->Peek8(addr); ! 140: } ! 141: ! 142: // このアドレスを担当する次段の IODevice を返す (IOContainerDevice 用) ! 143: IODevice * ! 144: XPbusDevice::GetDevice(uint32 addr) const ! 145: { ! 146: return SearchDevice(addr & 0x000fffff); ! 147: } ! 148: ! 149: // RMCR レジスタを取得する ! 150: uint32 ! 151: XPbusDevice::GetRMCR() const ! 152: { ! 153: return (ram_addr >> 12) & 0xff; ! 154: } ! 155: ! 156: // RMCR レジスタを設定する ! 157: void ! 158: XPbusDevice::SetRMCR(uint32 data) ! 159: { ! 160: ram_addr = ((data & 0xf0) << 12) | 0xfe00; ! 161: } ! 162: ! 163: ! 164: // ! 165: // XP 内蔵 512 バイト RAM ! 166: // ! 167: // IODevice にしておかないといけない関係で独立して用意する。 ! 168: // ここは RAM 実体を持っているだけで、配置場所は XPbusDevice が担当している。 ! 169: // ! 170: ! 171: // コンストラクタ ! 172: XPRAMDevice::XPRAMDevice() ! 173: : inherited(OBJ_XPRAM) ! 174: { ! 175: } ! 176: ! 177: // デストラクタ ! 178: XPRAMDevice::~XPRAMDevice() ! 179: { ! 180: } ! 181: ! 182: uint64 ! 183: XPRAMDevice::Read8(uint32 addr) ! 184: { ! 185: addr &= 0x1ff; ! 186: return ram[addr]; ! 187: } ! 188: ! 189: uint64 ! 190: XPRAMDevice::Read16(uint32 addr) ! 191: { ! 192: putlog(0, "should not be called?"); ! 193: return (uint64)-1; ! 194: } ! 195: ! 196: uint64 ! 197: XPRAMDevice::Read32(uint32 addr) ! 198: { ! 199: putlog(0, "should not be called?"); ! 200: return (uint64)-1; ! 201: } ! 202: ! 203: uint64 ! 204: XPRAMDevice::Write8(uint32 addr, uint32 data) ! 205: { ! 206: addr &= 0x1ff; ! 207: ram[addr] = data; ! 208: return 0; ! 209: } ! 210: ! 211: uint64 ! 212: XPRAMDevice::Write16(uint32 addr, uint32 data) ! 213: { ! 214: putlog(0, "should not be called?"); ! 215: return (uint64)-1; ! 216: } ! 217: ! 218: uint64 ! 219: XPRAMDevice::Write32(uint32 addr, uint32 data) ! 220: { ! 221: putlog(0, "should not be called?"); ! 222: return (uint64)-1; ! 223: } ! 224: ! 225: uint64 ! 226: XPRAMDevice::Peek8(uint32 addr) ! 227: { ! 228: addr &= 0x1ff; ! 229: return ram[addr]; ! 230: } ! 231: ! 232: uint64 ! 233: XPRAMDevice::Poke8(uint32 addr, uint32 data) ! 234: { ! 235: if ((int32)data >= 0) { ! 236: addr &= 0x1ff; ! 237: ram[addr] = data; ! 238: } ! 239: return 0; ! 240: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.