|
|
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.