|
|
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"
16:
17: // コンストラクタ
1.1.1.3 ! root 18: BankRAMDevice::BankRAMDevice(uint objid_, int ram_size_MB)
1.1 root 19: : inherited(objid_)
20: {
21: // ram_size_MB は正数のみ。負数は親側で処理する。
22: assert(ram_size_MB >= 0);
23:
24: ram_size = ram_size_MB * 1024 * 1024;
25: // 初期化は Init() で行う
26: }
27:
28: // デストラクタ
29: BankRAMDevice::~BankRAMDevice()
30: {
31: }
32:
33: // 初期化
34: bool
35: BankRAMDevice::Init()
36: {
37: if (inherited::Init() == false) {
38: return false;
39: }
40:
41: ram.reset(new uint8[ram_size]);
42:
43: return true;
44: }
45:
46: // 電源オン/リセット
47: void
48: BankRAMDevice::ResetHard(bool poweron)
49: {
50: if (poweron) {
51: // ノイズで埋めたいがとりあえず。
52: memset(&ram[0], 0, ram_size);
53: }
54:
55: // リセットでクリアされる。
56: SetPage(0);
1.1.1.2 root 57:
1.1.1.3 ! root 58: memset(&accstat_read[0], 0, AccStat::BANKLEN);
! 59: memset(&accstat_write[0], 0, AccStat::BANKLEN);
1.1 root 60: }
61:
62: inline uint32
63: BankRAMDevice::Decoder(uint32 addr) const
64: {
65: return pageaddr + (addr & 0xffff);
66: }
67:
1.1.1.2 root 68: busdata
1.1.1.3 ! root 69: BankRAMDevice::Read(busaddr addr)
1.1 root 70: {
1.1.1.3 ! root 71: uint32 offset = Decoder(addr.Addr());
! 72: busdata data;
1.1 root 73:
1.1.1.3 ! root 74: accstat_read[offset >> AccStat::SHIFT] = AccStat::READ;
1.1 root 75:
1.1.1.3 ! root 76: data = *(uint32 *)&ram[offset & ~3U];
! 77: putlog(4, "$%06x ($%06x) -> $%08x", addr.Addr(), offset, data.Data());
! 78: data |= busdata::Wait(1);
! 79: data |= BusData::Size4;
1.1 root 80: return data;
81: }
82:
1.1.1.2 root 83: busdata
1.1.1.3 ! root 84: BankRAMDevice::Write(busaddr addr, uint32 data)
1.1 root 85: {
1.1.1.3 ! root 86: uint32 offset = Decoder(addr.Addr());
! 87: uint32 reqsize = addr.GetSize();
! 88: uint32 datasize = std::min(4 - (offset & 3U), reqsize);
! 89:
! 90: accstat_write[offset >> AccStat::SHIFT] = AccStat::WRITE;
! 91:
! 92: if (datasize == 4) {
! 93: putlog(3, "$%06x ($%06x) <- $%08x", addr.Addr(), offset, data);
! 94: *(uint32 *)&ram[offset] = data;
! 95: } else if (datasize == 1) {
! 96: data >>= (reqsize - datasize) * 8;
! 97: putlog(3, "$%06x ($%06x) <- $%02x", addr.Addr(), offset, data);
! 98: ram[HLB(offset)] = data;
! 99: } else {
! 100: data >>= (reqsize - datasize) * 8;
! 101: putlog(3, "$%06x ($%06x) <- $%0*x", addr.Addr(), offset,
! 102: datasize * 2, data);
! 103: for (int i = datasize - 1; i >= 0; i--) {
! 104: ram[HLB(offset + i)] = data;
! 105: data >>= 8;
! 106: }
! 107: }
1.1 root 108:
1.1.1.3 ! root 109: busdata r = busdata::Wait(1);
! 110: r |= BusData::Size4;
! 111: return r;
1.1 root 112: }
113:
1.1.1.2 root 114: busdata
1.1.1.3 ! root 115: BankRAMDevice::Peek1(uint32 addr)
1.1 root 116: {
117: uint32 offset = Decoder(addr);
118: return ram[HLB(offset)];
119: }
120:
1.1.1.2 root 121: bool
1.1.1.3 ! root 122: BankRAMDevice::Poke1(uint32 addr, uint32 data)
1.1 root 123: {
124: if ((int32)data >= 0) {
125: uint32 offset = Decoder(addr);
126: ram[HLB(offset)] = data;
127: }
1.1.1.2 root 128: return true;
1.1 root 129: }
130:
131: void
132: BankRAMDevice::SetPage(uint32 page_)
133: {
134: page = page_;
135: // XXX 4MB の時の折返し確認
136: pageaddr = (page << 16) & (ram_size - 1);
137:
138: putlog(2, "Page <- $%02x", page);
139: }
1.1.1.2 root 140:
141: void
142: BankRAMDevice::FetchAccStat(uint8 *acc)
143: {
1.1.1.3 ! root 144: // 要素が8バイトと分かっていればこれだけで済む。
! 145: static_assert(AccStat::BANKLEN == 8, "");
! 146:
1.1.1.2 root 147: // R|W をマージしながらコピー。
1.1.1.3 ! root 148: uint64 tmp;
! 149: tmp = *(uint64 *)&accstat_read[0];
! 150: tmp |= *(uint64 *)&accstat_write[0];
! 151: *(uint64 *)acc = tmp;
1.1.1.2 root 152:
153: // 読んだのでリセット。
1.1.1.3 ! root 154: memset(&accstat_read[0], 0, AccStat::BANKLEN);
! 155: memset(&accstat_write[0], 0, AccStat::BANKLEN);
1.1.1.2 root 156: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.