|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // サブメモリ
9: //
10:
11: // SubRAM はバイト配置とする。
12:
13: #include "subram.h"
14: #include "mainapp.h"
15:
16: //
17: // 共通クラス
18: //
19:
20: // コンストラクタ
1.1.1.3 root 21: SubRAMBaseDevice::SubRAMBaseDevice(uint objid_, uint ramsize_kb)
1.1 root 22: : inherited(objid_)
23: {
1.1.1.3 root 24: uint ramsize = ramsize_kb * 1024;
25: assert((ramsize & (ramsize - 1)) == 0);
1.1 root 26:
1.1.1.3 root 27: mask = ramsize - 1;
1.1 root 28: }
29:
30: // デストラクタ
31: SubRAMBaseDevice::~SubRAMBaseDevice()
32: {
33: }
34:
1.1.1.4 root 35: // 初期化
36: bool
37: SubRAMBaseDevice::Init()
38: {
39: uint ramsize = GetSize();
40: ram.reset(new(std::nothrow) uint8[ramsize]);
41: if ((bool)ram == false) {
1.1.1.5 ! root 42: warnx("Could not allocate %u bytes at %s", ramsize, __method__);
1.1.1.4 root 43: return false;
44: }
45: memset(&ram[0], 0, ramsize);
46:
47: return true;
48: }
49:
1.1 root 50: // リセット
51: void
52: SubRAMBaseDevice::ResetHard(bool poweron)
53: {
54: if (poweron) {
55: // 実際にはゼロ初期化ではなくゴミだと思うがとりあえず。
1.1.1.3 root 56: memset(&ram[0], 0, GetSize());
1.1 root 57: }
58: }
59:
60: // アドレスデコーダ
1.1.1.2 root 61: inline uint32
1.1 root 62: SubRAMBaseDevice::Decoder(uint32 addr) const
63: {
1.1.1.3 root 64: // たぶんサイズ分で折り返しイメージが見えるはず。要確認。
65: return addr & mask;
1.1 root 66: }
67:
1.1.1.3 root 68: // MPU からのアクセス
1.1.1.2 root 69: busdata
1.1.1.3 root 70: SubRAMBaseDevice::Read(busaddr addr)
1.1 root 71: {
1.1.1.3 root 72: uint32 offset = Decoder(addr.Addr());
73: busdata data;
74:
75: // MPU からはおそらくロングワードデバイス。
76: data = be32toh(*(uint32 *)&ram[offset & ~3U]);
77: data |= BusData::Size4;
78: putlog(4, "$%08x -> $%08x", addr.Addr(), data.Data());
1.1 root 79: return data;
80: }
81:
1.1.1.3 root 82: // MPU からのアクセス
83: busdata
84: SubRAMBaseDevice::Write(busaddr addr, uint32 data)
85: {
86: uint32 offset = Decoder(addr.Addr());
87: uint32 reqsize = addr.GetSize();
88: uint32 datasize = std::min(4 - (offset & 3U), reqsize);
89:
90: // MPU からはおそらくロングワードデバイス。
91: if (datasize == 4) {
92: putlog(3, "$%08x <- $%08x", addr.Addr(), data);
93: *(uint32 *)&ram[offset] = htobe32(data);
94: } else if (datasize == 1) {
95: data >>= (reqsize - datasize) * 8;
96: putlog(3, "$%08x <- $%02x", addr.Addr(), data);
97: ram[offset] = data;
98: } else {
99: data >>= (reqsize - datasize) * 8;
100: putlog(3, "$%08x <- $%0*x", addr.Addr(), datasize * 2, data);
101: for (int i = datasize - 1; i >= 0; i--) {
102: ram[offset + i] = data;
103: data >>= 8;
104: }
105: }
106:
107: busdata r = BusData::Size4;
108: return r;
109: }
110:
1.1.1.2 root 111: busdata
1.1.1.3 root 112: SubRAMBaseDevice::Peek1(uint32 addr)
1.1 root 113: {
114: uint32 offset = Decoder(addr);
1.1.1.3 root 115: return ram[offset];
116: }
117:
118: bool
119: SubRAMBaseDevice::Poke1(uint32 addr, uint32 data)
120: {
121: if ((int32)data >= 0) {
122: uint32 offset = Decoder(addr);
123: ram[offset] = data;
124: }
125: return true;
1.1 root 126: }
127:
1.1.1.3 root 128: // XP からのバイト読み込み。
129: // (サイズは自明なので返さない)
1.1.1.2 root 130: busdata
1.1.1.3 root 131: SubRAMBaseDevice::Read1(uint32 addr)
1.1 root 132: {
133: uint32 offset = Decoder(addr);
1.1.1.3 root 134: busdata data = ram[offset];
135: putlog(4, "XP $%05x -> $%02x", offset, data.Data());
1.1 root 136: return data;
137: }
138:
1.1.1.3 root 139: // XP からのバイト書き込み。
140: // (サイズは自明なので返さない)
1.1.1.2 root 141: busdata
1.1.1.3 root 142: SubRAMBaseDevice::Write1(uint32 addr, uint32 data)
1.1 root 143: {
144: uint32 offset = Decoder(addr);
1.1.1.3 root 145: putlog(3, "XP $%05x <- $%02x", offset, data);
1.1 root 146: ram[offset] = data;
147: return 0;
148: }
149:
1.1.1.3 root 150: // Lance からのワード読み込み。addr は偶数であること。
151: // (サイズは自明なので返さない)
1.1.1.2 root 152: busdata
1.1.1.3 root 153: SubRAMBaseDevice::Read2(uint32 addr)
1.1 root 154: {
1.1.1.3 root 155: busdata data = Peek2(addr);
156: putlog(4, "LE $%05x -> $%04x", Decoder(addr), data.Data());
157: return data;
1.1 root 158: }
159:
1.1.1.3 root 160: // Lance からのワード書き込み。addr は偶数であること。
161: // (サイズは自明なので返さない)
1.1.1.2 root 162: busdata
1.1.1.3 root 163: SubRAMBaseDevice::Write2(uint32 addr, uint32 data)
1.1 root 164: {
165: uint32 offset = Decoder(addr);
1.1.1.3 root 166: putlog(3, "LE $%05x <- $%04x", offset, data);
167: *(uint16 *)&ram[offset] = htobe16(data);
1.1 root 168: return 0;
169: }
170:
1.1.1.3 root 171: // Lance からのピーク。addr は偶数であること。
1.1.1.2 root 172: busdata
1.1.1.3 root 173: SubRAMBaseDevice::Peek2(uint32 addr) const
1.1 root 174: {
175: uint32 offset = Decoder(addr);
1.1.1.3 root 176: busdata data = be16toh(*(uint16 *)&ram[offset]);
177: return data;
1.1 root 178: }
179:
180:
181: //
1.1.1.3 root 182: // サブメモリ 1 (XP/Lance との共有 RAM)
1.1 root 183: //
184:
185: // コンストラクタ
1.1.1.3 root 186: SubRAMDevice::SubRAMDevice(uint ramsize_kb)
1.1 root 187: : inherited(OBJ_SUBRAM, ramsize_kb)
188: {
189: }
190:
191: // デストラクタ
192: SubRAMDevice::~SubRAMDevice()
193: {
194: }
195:
196: // リセット
197: void
198: SubRAMDevice::ResetHard(bool poweron)
199: {
200: // 通常モードなら電源オンで初期化。
201: // MSXDOS モードなら MSXDOSDevice::Init() がすでにここに
202: // 書き込んでいるため、消してはいけない。
203: if (gMainApp.msxdos_mode == false) {
204: inherited::ResetHard(poweron);
205: }
206: }
207:
208:
209: //
1.1.1.3 root 210: // サブメモリ 2 (XP の非共有部)
1.1 root 211: //
212:
213: // コンストラクタ
1.1.1.3 root 214: SubRAM2Device::SubRAM2Device(uint ramsize_kb)
1.1 root 215: : inherited(OBJ_SUBRAM2, ramsize_kb)
216: {
217: }
218:
219: // デストラクタ
220: SubRAM2Device::~SubRAM2Device()
221: {
222: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.