|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2024 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
1.1.1.2 root 8: // メインバス (virt-m68k)
1.1 root 9: //
10:
11: // IODevice
12: // +-- MainbusBaseDevice (InitMainbus() と FC アクセスを持つ)
13: // | +-- MainbusDevice (これがメインバス、システムに1つ)
14: // | | +-- Mainbus24Device (上位8ビットがテーブルで表せるメインバス)
15: // | | | +-- LunaMainbus
16: // | | | | +-- Luna1Mainbus
17: // | | | | +-- Luna88kMainbus
18: // | | | +-- NewsMainbus
1.1.1.2 root 19: // | | |
20: // | | | +----------------+
21: // | | +--| Virt68kMainbus |
22: // | | | +----------------+
1.1 root 23: // | | |
24: // | | +-- X68kMainbus
25: // | +-- X68kIODevice
26: // +-- XPbusDevice
27:
28: #include "mainbus_virt68k.h"
1.1.1.4 root 29: #include "buserr.h"
1.1 root 30: #include "interrupt.h"
31: #include "mainapp.h"
32: #include "mainram.h"
1.1.1.3 root 33: #include "monitor.h"
1.1 root 34: #include "v68kio.h"
35:
36: // コンストラクタ
37: Virt68kMainbus::Virt68kMainbus()
1.1.1.2 root 38: : inherited(OBJ_MAINBUS)
1.1 root 39: {
40: NEWDV(BusErr, new BusErrDevice());
41: NEWDV(Interrupt, new Virt68kInterrupt());
42: NEWDV(MainRAM, new MainRAMDevice());
43: NEWDV(V68kIO, new V68kIODevice());
44:
45: // メインメモリは Init() で設定する。
46:
1.1.1.3 root 47: accstat_monitor->SetSize(80, 2 + 32);
1.1 root 48: }
49:
50: // デストラクタ
51: Virt68kMainbus::~Virt68kMainbus()
52: {
53: }
54:
55: // メインバスの初期化
56: bool
57: Virt68kMainbus::InitMainbus()
58: {
59: // RAM は容量が確定した後のここで配置。
60: // 16MB 単位になっている。
61: auto mainram = dynamic_cast<MainRAMDevice *>(pMainRAM.get());
1.1.1.2 root 62: ramsize = mainram->GetSize();
1.1 root 63:
64: // アクセス状況用のマップを作成。
1.1.1.2 root 65: for (uint32 i = 0; i < 4096 / 16; i++) {
66: if (Decoder(i * 0x0100'0000) != pBusErr.get()) {
67: accstat_avail[i / 8] |= 0x80U >> (i % 8);
68: }
69: }
1.1 root 70:
71: return true;
72: }
73:
1.1.1.2 root 74: inline IODevice *
75: Virt68kMainbus::Decoder(uint32 addr) const
76: {
77: if (__predict_true(addr < ramsize)) {
78: return pMainRAM.get();
79: } else if (__predict_true(addr >= 0xff000000)) {
80: return pV68kIO.get();
81: } else {
82: return pBusErr.get();
83: }
84: }
85:
86: busdata
87: Virt68kMainbus::Read(busaddr addr)
88: {
89: uint32 pa = addr.Addr();
1.1.1.5 ! root 90: lastaddr = pa;
1.1.1.2 root 91: accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
92: IODevice *dev = Decoder(pa);
93: return dev->Read(addr);
94: }
95:
96: busdata
97: Virt68kMainbus::Write(busaddr addr, uint32 data)
98: {
99: uint32 pa = addr.Addr();
1.1.1.5 ! root 100: lastaddr = pa;
1.1.1.2 root 101: accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE;
102: IODevice *dev = Decoder(pa);
103: return dev->Write(addr, data);
104: }
105:
106: busdata
107: Virt68kMainbus::ReadBurst16(busaddr addr, uint32 *dst)
108: {
109: uint32 pa = addr.Addr();
1.1.1.5 ! root 110: lastaddr = pa; // 開始アドレスしか残らない…
1.1.1.2 root 111: IODevice *dev = Decoder(pa);
112: busdata r = dev->ReadBurst16(addr, dst);
113: if (__predict_true(r.IsBusErr() == false)) {
114: accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
115: }
116: return r;
117: }
118:
119: busdata
120: Virt68kMainbus::WriteBurst16(busaddr addr, const uint32 *src)
121: {
122: uint32 pa = addr.Addr();
1.1.1.5 ! root 123: lastaddr = pa; // 開始アドレスしか残らない…
1.1.1.2 root 124: IODevice *dev = Decoder(pa);
125: busdata r = dev->WriteBurst16(addr, src);
126: if (__predict_true(r.IsBusErr() == false)) {
127: accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE;
128: }
129: return r;
130: }
131:
132: busdata
133: Virt68kMainbus::Peek1(uint32 addr)
134: {
135: IODevice *dev = Decoder(addr);
136: return dev->Peek1(addr);
137: }
138:
139: bool
140: Virt68kMainbus::Poke1(uint32 addr, uint32 data)
141: {
142: IODevice *dev = Decoder(addr);
143: return dev->Poke1(addr, data);
144: }
145:
1.1 root 146: // ブートページを切り替える。
147: void
148: Virt68kMainbus::SwitchBootPage(bool isram)
149: {
150: // まだサポートしていない。
151: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.