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