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