|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2023 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // X68030 勝手に拡張メモリ
9: //
10: // 拡張メモリは TS-6BE16 互換か 060turbo 互換のいずれか。
11: // TS-6BE16 互換だと $0100'0000 〜 $01ff'ffff の 16MB。
12: // 060turbo 互換だと $1000'0000 〜 $17ff'ffff の 128MB、
13: // $1000'0000 〜 $1fff'ffff の 256MB。
1.1.1.3 root 14: // $1000'0000 〜 $2fff'ffff の 512MB。(独自拡張)
1.1 root 15: //
16:
17: // 拡張 RAM はロングワード単位でホストバイトオーダ配置なので、
18: // バイトアクセス、ワードアクセス時は HLB(), HLW() マクロを使用のこと。
19:
20: #include "extram.h"
21: #include "config.h"
22:
23: // コンストラクタ
24: ExtRAMDevice::ExtRAMDevice()
25: : inherited(OBJ_EXTRAM)
26: {
27: }
28:
29: // デストラクタ
30: ExtRAMDevice::~ExtRAMDevice()
31: {
32: }
33:
34: // 初期化
35: bool
36: ExtRAMDevice::Init()
37: {
38: if (inherited::Init() == false) {
39: return false;
40: }
41:
42: const ConfigItem& item = gConfig->Find("extram-size");
43: uint32 extram_size_MB = item.AsInt();
1.1.1.4 ! root 44: if (extram_size_MB == 0) {
1.1 root 45: return true;
46: }
47: switch (extram_size_MB) {
48: case 16:
49: ram_addr = 0x01'000000;
50: break;
51: case 128:
52: case 256:
1.1.1.3 root 53: case 384:
54: case 512:
1.1 root 55: ram_addr = 0x10'000000;
56: break;
57: default:
1.1.1.3 root 58: item.Err("Valid size are 16, 128, 256, 384 or 512 for now");
1.1 root 59: return false;
60: }
61:
62: ram_size = extram_size_MB * 1024 * 1024;
1.1.1.3 root 63: ram.reset(new(std::nothrow) uint8[ram_size]);
64: if ((bool)ram == false) {
65: errno = ENOMEM;
66: warn("ExtRAM(%u bytes)", ram_size);
67: return false;
68: }
1.1 root 69:
70: return true;
71: }
72:
73: // 電源オン/リセット
74: void
75: ExtRAMDevice::ResetHard(bool poweron)
76: {
77: if (poweron) {
78: // ノイズで埋めたいがとりあえず。
79: memset(&ram[0], 0, ram_size);
80: }
81: }
82:
83: inline uint32
84: ExtRAMDevice::Decoder(uint32 addr) const
85: {
86: return (addr - ram_addr);
87: }
88:
1.1.1.3 root 89: busdata
1.1.1.4 ! root 90: ExtRAMDevice::Read(busaddr addr)
1.1 root 91: {
1.1.1.4 ! root 92: uint32 offset = Decoder(addr.Addr());
! 93: busdata data;
1.1 root 94:
1.1.1.4 ! root 95: data = *(uint32 *)&ram[offset & ~3U];
! 96: putlog(4, "$%08x -> $%08x", addr.Addr(), data.Data());
! 97: data |= BusData::Size4;
1.1 root 98: return data;
99: }
100:
1.1.1.3 root 101: busdata
1.1.1.4 ! root 102: ExtRAMDevice::Write(busaddr addr, uint32 data)
1.1 root 103: {
1.1.1.4 ! root 104: uint32 paddr = Decoder(addr.Addr());
! 105: uint32 reqsize = addr.GetSize();
! 106: uint32 datasize = std::min(4 - (paddr & 3U), reqsize);
! 107:
! 108: if (datasize == 4) {
! 109: *(uint32 *)&ram[paddr] = data;
! 110: putlog(3, "$%08x <- $%08x", addr.Addr(), data);
! 111: } else {
! 112: data >>= (reqsize - datasize) * 8;
! 113: putlog(3, "$%08x <- $%0*x", addr.Addr(), datasize * 2, data);
! 114: for (int i = datasize - 1; i >= 0; i--) {
! 115: ram[HLB(paddr + i)] = data;
! 116: data >>= 8;
! 117: }
! 118: }
1.1 root 119:
1.1.1.4 ! root 120: busdata r = BusData::Size4;
! 121: return r;
1.1 root 122: }
123:
1.1.1.3 root 124: busdata
1.1.1.4 ! root 125: ExtRAMDevice::Peek1(uint32 addr)
1.1 root 126: {
127: uint32 offset = Decoder(addr);
128: return ram[HLB(offset)];
129: }
130:
1.1.1.3 root 131: bool
1.1.1.4 ! root 132: ExtRAMDevice::Poke1(uint32 addr, uint32 data)
1.1 root 133: {
134: if ((int32)data >= 0) {
135: uint32 offset = Decoder(addr);
136: ram[HLB(offset)] = data;
137: }
1.1.1.3 root 138: return true;
1.1 root 139: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.