|
|
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"
29: #include "interrupt.h"
30: #include "mainapp.h"
31: #include "mainram.h"
32: #include "v68kio.h"
33:
34: // コンストラクタ
35: Virt68kMainbus::Virt68kMainbus()
1.1.1.2 ! root 36: : inherited(OBJ_MAINBUS)
1.1 root 37: {
38: NEWDV(BusErr, new BusErrDevice());
39: NEWDV(Interrupt, new Virt68kInterrupt());
40: NEWDV(MainRAM, new MainRAMDevice());
41: NEWDV(V68kIO, new V68kIODevice());
42:
43: // メインメモリは Init() で設定する。
44:
45: monitor_accstat.SetSize(80, 2 + 32);
46: }
47:
48: // デストラクタ
49: Virt68kMainbus::~Virt68kMainbus()
50: {
51: }
52:
53: // メインバスの初期化
54: bool
55: Virt68kMainbus::InitMainbus()
56: {
57: // RAM は容量が確定した後のここで配置。
58: // 16MB 単位になっている。
59: auto mainram = dynamic_cast<MainRAMDevice *>(pMainRAM.get());
1.1.1.2 ! root 60: ramsize = mainram->GetSize();
1.1 root 61:
62: // アクセス状況用のマップを作成。
1.1.1.2 ! root 63: for (uint32 i = 0; i < 4096 / 16; i++) {
! 64: if (Decoder(i * 0x0100'0000) != pBusErr.get()) {
! 65: accstat_avail[i / 8] |= 0x80U >> (i % 8);
! 66: }
! 67: }
1.1 root 68:
69: return true;
70: }
71:
1.1.1.2 ! root 72: inline IODevice *
! 73: Virt68kMainbus::Decoder(uint32 addr) const
! 74: {
! 75: if (__predict_true(addr < ramsize)) {
! 76: return pMainRAM.get();
! 77: } else if (__predict_true(addr >= 0xff000000)) {
! 78: return pV68kIO.get();
! 79: } else {
! 80: return pBusErr.get();
! 81: }
! 82: }
! 83:
! 84: busdata
! 85: Virt68kMainbus::Read(busaddr addr)
! 86: {
! 87: uint32 pa = addr.Addr();
! 88: accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
! 89: IODevice *dev = Decoder(pa);
! 90: return dev->Read(addr);
! 91: }
! 92:
! 93: busdata
! 94: Virt68kMainbus::Write(busaddr addr, uint32 data)
! 95: {
! 96: uint32 pa = addr.Addr();
! 97: accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE;
! 98: IODevice *dev = Decoder(pa);
! 99: return dev->Write(addr, data);
! 100: }
! 101:
! 102: busdata
! 103: Virt68kMainbus::ReadBurst16(busaddr addr, uint32 *dst)
! 104: {
! 105: uint32 pa = addr.Addr();
! 106: IODevice *dev = Decoder(pa);
! 107: busdata r = dev->ReadBurst16(addr, dst);
! 108: if (__predict_true(r.IsBusErr() == false)) {
! 109: accstat_read[pa >> AccStat::SHIFT] = AccStat::READ;
! 110: }
! 111: return r;
! 112: }
! 113:
! 114: busdata
! 115: Virt68kMainbus::WriteBurst16(busaddr addr, const uint32 *src)
! 116: {
! 117: uint32 pa = addr.Addr();
! 118: IODevice *dev = Decoder(pa);
! 119: busdata r = dev->WriteBurst16(addr, src);
! 120: if (__predict_true(r.IsBusErr() == false)) {
! 121: accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE;
! 122: }
! 123: return r;
! 124: }
! 125:
! 126: busdata
! 127: Virt68kMainbus::Peek1(uint32 addr)
! 128: {
! 129: IODevice *dev = Decoder(addr);
! 130: return dev->Peek1(addr);
! 131: }
! 132:
! 133: bool
! 134: Virt68kMainbus::Poke1(uint32 addr, uint32 data)
! 135: {
! 136: IODevice *dev = Decoder(addr);
! 137: return dev->Poke1(addr, data);
! 138: }
! 139:
1.1 root 140: // ブートページを切り替える。
141: void
142: Virt68kMainbus::SwitchBootPage(bool isram)
143: {
144: // まだサポートしていない。
145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.