|
|
1.1 root 1: //
2: // nono
1.1.1.4 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: //
8: // SRAM
9: //
1.1.1.9 root 10:
1.1 root 11: // SRAM はビッグエンディアンのままメモリに置かれるので、
12: // 必要ならアクセス時に都度変換すること。
13:
1.1.1.9 root 14: #include "sram.h"
1.1.1.10 root 15: #include "config.h"
1.1.1.9 root 16: #include "mainapp.h"
1.1.1.11! root 17: #include "mainram.h"
1.1.1.10 root 18: #include <array>
1.1.1.9 root 19:
20: // コンストラクタ
1.1 root 21: SRAMDevice::SRAMDevice()
1.1.1.11! root 22: : inherited(OBJ_SRAM)
1.1 root 23: {
24: }
25:
1.1.1.9 root 26: // デストラクタ
1.1 root 27: SRAMDevice::~SRAMDevice()
28: {
29: }
30:
1.1.1.11! root 31: // 初期化
1.1 root 32: bool
33: SRAMDevice::Init()
34: {
1.1.1.11! root 35: if (inherited::Init() == false) {
! 36: return false;
! 37: }
! 38:
1.1.1.10 root 39: filename = gMainApp.GetVMDir() + "SRAM.DAT";
1.1.1.4 root 40: file.SetFilename(filename);
41: file.SetDispname(string_format("SRAM \"%s\"", filename.c_str()));
42: mem = file.OpenCreate(16 * 1024);
43: if (mem == NULL) {
1.1 root 44: return false;
45: }
46:
1.1.1.10 root 47: // SRAM の RAM 容量欄を設定値に同期させる。
48: // この処理はアプリケーション起動時に一回行われるのみで、
49: // その後の VM 内のリセット等では動作しない。
50: bool sync = gConfig->Find("sram-sync-ramsize").AsInt();
51: if (sync) {
52: SyncRAMSize();
53: }
54:
1.1 root 55: return true;
56: }
57:
1.1.1.9 root 58: // リセット
1.1.1.6 root 59: void
1.1.1.9 root 60: SRAMDevice::ResetHard(bool poweron)
1.1.1.6 root 61: {
62: // XXX 未調査
63: writeable = false;
64: }
65:
1.1.1.10 root 66: // SRAM の RAM 容量欄を設定値に同期させる。
67: void
68: SRAMDevice::SyncRAMSize()
69: {
70: // SRAM の内容が無効なら何もしない。
71: static const std::array<uint8, 7> magic {
72: 0x82, 0x77, '6', '8', '0', '0', '0'
73: };
74: for (int i = 0; i < magic.size(); i++) {
75: if (mem[i] != magic[i]) {
76: return;
77: }
78: }
79:
1.1.1.11! root 80: uint32 ramsize = GetMainRAMDevice()->GetSize();
1.1.1.10 root 81:
82: // 値が違う時だけ表示したいので一旦読み出して比較
83: uint32 cursize;
84: cursize = mem[0x08] << 24;
85: cursize |= mem[0x09] << 16;
86: cursize |= mem[0x0a] << 8;
87: cursize |= mem[0x0b];
88: if (cursize != ramsize) {
89: // ここは Init() なので putmsg() は使えない
90: warnx("SRAM: Update ramsize %dMB", ramsize / 1024 / 1024);
91:
92: mem[0x08] = ramsize >> 24;
93: mem[0x09] = ramsize >> 16;
94: mem[0x0a] = ramsize >> 8;
95: mem[0x0b] = ramsize;
96: }
97: }
98:
1.1.1.3 root 99: // アドレスデコーダ
100: inline uint64
101: SRAMDevice::Decoder(uint32 addr) const
102: {
1.1.1.4 root 103: uint32 offset = addr - baseaddr;
104: assertmsg(offset < file.GetMemSize(),
105: "offset=%x memlen=%x", offset, (int)file.GetMemSize());
106: return offset;
1.1.1.3 root 107: }
108:
1.1 root 109: uint64
110: SRAMDevice::Read8(uint32 addr)
111: {
1.1.1.3 root 112: uint32 offset = Decoder(addr);
1.1.1.4 root 113: uint32 data;
114:
1.1.1.11! root 115: data = Get8(offset);
! 116: putlog(2, "$%06x.B -> $%02x", addr, data);
1.1.1.4 root 117:
118: return data;
1.1 root 119: }
120:
121: uint64
122: SRAMDevice::Read16(uint32 addr)
123: {
1.1.1.3 root 124: uint32 offset = Decoder(addr);
1.1.1.4 root 125: uint32 data;
126:
1.1.1.11! root 127: data = Get16(offset);
! 128: putlog(2, "$%06x.W -> $%04x", addr, data);
1.1.1.4 root 129:
130: return data;
1.1 root 131: }
132:
133: uint64
134: SRAMDevice::Write8(uint32 addr, uint32 data)
135: {
1.1.1.3 root 136: uint32 offset = Decoder(addr);
137:
1.1 root 138: if (writeable) {
1.1.1.3 root 139: if (offset < 0x100) {
1.1.1.10 root 140: putlog(1, "$%06x.B <- $%02x", addr, data);
1.1 root 141: }
1.1.1.3 root 142: mem[offset] = data;
1.1 root 143: } else {
1.1.1.10 root 144: putlog(1, "Write protected $%06x.B <- $%02x", addr, data);
1.1 root 145: }
146: return 0;
147: }
148:
149: uint64
150: SRAMDevice::Write16(uint32 addr, uint32 data)
151: {
1.1.1.3 root 152: uint32 offset = Decoder(addr);
153:
1.1 root 154: if (writeable) {
1.1.1.3 root 155: if (offset < 0x100) {
1.1.1.10 root 156: putlog(1, "$%06x.W <- $%04x", addr, data);
1.1 root 157: }
1.1.1.3 root 158: *(uint16 *)&mem[offset] = htobe16(data);
1.1 root 159: } else {
1.1.1.10 root 160: putlog(1, "Write protected $%06x.W <- $%04x", addr, data);
1.1 root 161: }
162: return 0;
163: }
164:
165: uint64
166: SRAMDevice::Peek8(uint32 addr)
167: {
1.1.1.3 root 168: uint32 offset = Decoder(addr);
1.1.1.4 root 169:
1.1.1.11! root 170: return Get8(offset);
! 171: }
1.1.1.4 root 172:
1.1.1.11! root 173: uint64
! 174: SRAMDevice::Poke8(uint32 addr, uint32 data)
! 175: {
! 176: // WriteEnable() に関わらず変更する。
! 177: // また Get8()、Get16() はこの変更の影響を受けないことに注意。
! 178:
! 179: if ((int32)data >= 0) {
! 180: uint32 offset = Decoder(addr);
! 181: mem[offset] = data;
! 182: }
! 183: return 0;
1.1 root 184: }
185:
186: void
1.1.1.11! root 187: SRAMDevice::WriteEnable(bool value)
1.1 root 188: {
189: if (writeable == false && value == true) {
1.1.1.10 root 190: putlog(1, "Write Enable");
1.1 root 191: } else if (writeable == true && value == false) {
1.1.1.10 root 192: putlog(1, "Write Disable");
1.1 root 193: }
194:
195: writeable = value;
196: }
1.1.1.4 root 197:
1.1.1.11! root 198: // SRAM から副作用なく読み出す。
! 199: // ただしホストファイル起動モードなら改変した値を返す。
1.1.1.4 root 200: uint32
1.1.1.11! root 201: SRAMDevice::Get8(uint32 offset) const
1.1.1.4 root 202: {
1.1.1.11! root 203: if (gMainApp.exec_file) {
! 204: switch (offset) {
! 205: case 0x0c: // ROM 起動アドレス(.L)
! 206: return plutoaddr >> 24;
! 207: case 0x0d:
! 208: return (plutoaddr >> 16) & 0xff;
! 209: case 0x0e:
! 210: return (plutoaddr >> 8) & 0xff;
! 211: case 0x0f:
! 212: return plutoaddr & 0xff;
! 213:
! 214: case 0x18: // 起動デバイス(.W) を ROM($a000) にする
! 215: return 0xa0;
! 216: case 0x19:
! 217: return 0x00;
! 218:
! 219: default:
! 220: break;
! 221: }
1.1.1.4 root 222: }
1.1.1.11! root 223:
! 224: // 他は SRAM から
! 225: return mem[offset];
! 226: }
! 227:
! 228: // SRAM から副作用なくワードで読み出す。
! 229: // ただしホストファイル起動モードなら改変した値を返す。
! 230: uint32
! 231: SRAMDevice::Get16(uint32 offset) const
! 232: {
! 233: uint32 data;
! 234:
! 235: data = Get8(offset) << 8;
! 236: data |= Get8(offset + 1);
! 237:
! 238: return data;
1.1.1.4 root 239: }
1.1.1.10 root 240:
1.1.1.11! root 241: // SRAM から副作用なくロングワードで読み出す。
! 242: // ただしホストファイル起動モードなら改変した値を返す。
1.1.1.10 root 243: uint32
1.1.1.11! root 244: SRAMDevice::Get32(uint32 offset) const
1.1.1.10 root 245: {
246: uint32 data;
247:
1.1.1.11! root 248: data = Get16(offset) << 16;
! 249: data |= Get16(offset + 2);
1.1.1.10 root 250:
251: return data;
252: }
1.1.1.11! root 253:
! 254: // IPLROM30 が初期化した SRAM の初期値。
! 255: //
! 256: // 0000: 82 77 36 38 30 30 30 57 00 40 00 00 00 fc 00 00 |.w68000W.@......|
! 257: // 0010: 00 ed 01 00 ff ff ff ff 00 00 4e 07 00 10 00 00 |..........N.....|
! 258: // 0020: 00 00 ff ff 00 00 07 00 0e 00 0d 00 00 00 00 00 |................|
! 259: // 0030: f8 3e ff c0 ff fe de 6c 40 22 03 02 00 08 00 00 |.>.....l@"......|
! 260: // 0040: 00 00 00 00 00 00 00 00 00 ff f4 00 04 00 01 01 |................|
! 261: // 0050: 00 00 00 20 00 03 f9 01 00 00 00 00 00 00 00 00 |... ............|
! 262: /*static*/ std::array<uint8, 0x60>
! 263: SRAMDevice::InitialData {
! 264: 0x82, 0x77, 0x36, 0x38, 0x30, 0x30, 0x30, 0x57,
! 265: 0x00, 0x40, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
! 266: 0x00, 0xed, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff,
! 267: 0x00, 0x00, 0x4e, 0x07, 0x00, 0x10, 0x00, 0x00,
! 268: 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x07, 0x00,
! 269: 0x0e, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
! 270: 0xf8, 0x3e, 0xff, 0xc0, 0xff, 0xfe, 0xde, 0x6c,
! 271: 0x40, 0x22, 0x03, 0x02, 0x00, 0x08, 0x00, 0x00,
! 272: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 273: 0x00, 0xff, 0xf4, 0x00, 0x04, 0x00, 0x01, 0x01,
! 274: 0x00, 0x00, 0x00, 0x20, 0x00, 0x03, 0xf9, 0x01,
! 275: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
! 276: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.