|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2023 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // Nereid バンクメモリ
9: //
10:
11: // バンクメモリはロングワード単位でホストバイトオーダ配置なので、
12: // バイトアクセス、ワードアクセス時は HLB(), HLW() マクロを使用のこと。
13:
14: #include "bankram.h"
15: #include "config.h"
1.1.1.2 ! root 16: #include "mainbus.h"
1.1 root 17:
18: // コンストラクタ
19: BankRAMDevice::BankRAMDevice(int objid_, int ram_size_MB)
20: : inherited(objid_)
21: {
22: // ram_size_MB は正数のみ。負数は親側で処理する。
23: assert(ram_size_MB >= 0);
24:
25: ram_size = ram_size_MB * 1024 * 1024;
26: // 初期化は Init() で行う
27: }
28:
29: // デストラクタ
30: BankRAMDevice::~BankRAMDevice()
31: {
32: }
33:
34: // 初期化
35: bool
36: BankRAMDevice::Init()
37: {
38: if (inherited::Init() == false) {
39: return false;
40: }
41:
42: ram.reset(new uint8[ram_size]);
43:
44: return true;
45: }
46:
47: // 電源オン/リセット
48: void
49: BankRAMDevice::ResetHard(bool poweron)
50: {
51: if (poweron) {
52: // ノイズで埋めたいがとりあえず。
53: memset(&ram[0], 0, ram_size);
54: }
55:
56: // リセットでクリアされる。
57: SetPage(0);
1.1.1.2 ! root 58:
! 59: std::fill(accstat_read.begin(), accstat_read.end(), 0);
! 60: std::fill(accstat_write.begin(), accstat_write.end(), 0);
1.1 root 61: }
62:
63: inline uint32
64: BankRAMDevice::Decoder(uint32 addr) const
65: {
66: return pageaddr + (addr & 0xffff);
67: }
68:
1.1.1.2 ! root 69: busdata
1.1 root 70: BankRAMDevice::Read8(uint32 addr)
71: {
72: uint32 offset = Decoder(addr);
1.1.1.2 ! root 73: accstat_read[offset >> 20] = MainbusDevice::ACC_READ;
1.1 root 74: uint32 data = ram[HLB(offset)];
75: putlog(4, "$%08x.B -> $%02x", addr, data);
76: return data;
77: }
78:
1.1.1.2 ! root 79: busdata
1.1 root 80: BankRAMDevice::Read16(uint32 addr)
81: {
82: uint32 offset = Decoder(addr);
1.1.1.2 ! root 83: accstat_read[offset >> 20] = MainbusDevice::ACC_READ;
1.1 root 84: uint32 data = *(uint16 *)&ram[HLW(offset)];
85: putlog(4, "$%08x.W -> $%04x", addr, data);
86: return data;
87: }
88:
1.1.1.2 ! root 89: busdata
1.1 root 90: BankRAMDevice::Read32(uint32 addr)
91: {
92: uint32 offset = Decoder(addr);
1.1.1.2 ! root 93: accstat_read[offset >> 20] = MainbusDevice::ACC_READ;
1.1 root 94: uint32 data = *(uint32 *)&ram[offset];
95: putlog(4, "$%08x.L -> $%08x", addr, data);
96: return data;
97: }
98:
1.1.1.2 ! root 99: busdata
1.1 root 100: BankRAMDevice::Write8(uint32 addr, uint32 data)
101: {
102: uint32 offset = Decoder(addr);
1.1.1.2 ! root 103: accstat_write[offset >> 20] = MainbusDevice::ACC_WRITE;
1.1 root 104: ram[HLB(offset)] = data;
105: putlog(3, "$%08x.B <- $%02x", addr, data);
106: return 0;
107: }
108:
1.1.1.2 ! root 109: busdata
1.1 root 110: BankRAMDevice::Write16(uint32 addr, uint32 data)
111: {
112: uint32 offset = Decoder(addr);
1.1.1.2 ! root 113: accstat_write[offset >> 20] = MainbusDevice::ACC_WRITE;
1.1 root 114: *(uint16 *)&ram[HLW(offset)] = data;
115: putlog(3, "$%08x.W <- $%04x", addr, data);
116: return 0;
117: }
118:
1.1.1.2 ! root 119: busdata
1.1 root 120: BankRAMDevice::Write32(uint32 addr, uint32 data)
121: {
122: uint32 offset = Decoder(addr);
1.1.1.2 ! root 123: accstat_write[offset >> 20] = MainbusDevice::ACC_WRITE;
1.1 root 124: *(uint32 *)&ram[offset] = data;
125: putlog(3, "$%08x.L <- $%08x", addr, data);
126: return 0;
127: }
128:
1.1.1.2 ! root 129: busdata
1.1 root 130: BankRAMDevice::Peek8(uint32 addr)
131: {
132: uint32 offset = Decoder(addr);
133: return ram[HLB(offset)];
134: }
135:
1.1.1.2 ! root 136: bool
1.1 root 137: BankRAMDevice::Poke8(uint32 addr, uint32 data)
138: {
139: if ((int32)data >= 0) {
140: uint32 offset = Decoder(addr);
141: ram[HLB(offset)] = data;
142: }
1.1.1.2 ! root 143: return true;
1.1 root 144: }
145:
146: void
147: BankRAMDevice::SetPage(uint32 page_)
148: {
149: page = page_;
150: // XXX 4MB の時の折返し確認
151: pageaddr = (page << 16) & (ram_size - 1);
152:
153: putlog(2, "Page <- $%02x", page);
154: }
1.1.1.2 ! root 155:
! 156: void
! 157: BankRAMDevice::FetchAccStat(uint8 *acc)
! 158: {
! 159: // R|W をマージしながらコピー。
! 160: for (int i = 0; i < accstat_read.size(); i += 4) {
! 161: uint32 tmp = 0;
! 162: tmp |= *(uint32 *)&accstat_read[i];
! 163: tmp |= *(uint32 *)&accstat_write[i];
! 164: *(uint32 *)&acc[i] = tmp;
! 165: }
! 166:
! 167: // 読んだのでリセット。
! 168: std::fill(accstat_read.begin(), accstat_read.end(), 0);
! 169: std::fill(accstat_write.begin(), accstat_write.end(), 0);
! 170: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.