|
|
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();
90: accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
91: IODevice *dev = Decoder(pa);
92: return dev->Read(addr);
93: }
94:
95: busdata
96: Virt68kMainbus::Write(busaddr addr, uint32 data)
97: {
98: uint32 pa = addr.Addr();
99: accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE;
100: IODevice *dev = Decoder(pa);
101: return dev->Write(addr, data);
102: }
103:
104: busdata
105: Virt68kMainbus::ReadBurst16(busaddr addr, uint32 *dst)
106: {
107: uint32 pa = addr.Addr();
108: IODevice *dev = Decoder(pa);
109: busdata r = dev->ReadBurst16(addr, dst);
110: if (__predict_true(r.IsBusErr() == false)) {
111: accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
112: }
113: return r;
114: }
115:
116: busdata
117: Virt68kMainbus::WriteBurst16(busaddr addr, const uint32 *src)
118: {
119: uint32 pa = addr.Addr();
120: IODevice *dev = Decoder(pa);
121: busdata r = dev->WriteBurst16(addr, src);
122: if (__predict_true(r.IsBusErr() == false)) {
123: accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE;
124: }
125: return r;
126: }
127:
128: busdata
129: Virt68kMainbus::Peek1(uint32 addr)
130: {
131: IODevice *dev = Decoder(addr);
132: return dev->Peek1(addr);
133: }
134:
135: bool
136: Virt68kMainbus::Poke1(uint32 addr, uint32 data)
137: {
138: IODevice *dev = Decoder(addr);
139: return dev->Poke1(addr, data);
140: }
141:
1.1 root 142: // ブートページを切り替える。
143: void
144: Virt68kMainbus::SwitchBootPage(bool isram)
145: {
146: // まだサポートしていない。
147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.