--- nono/vm/mainbus_virt68k.cpp 2026/04/29 17:05:25 1.1 +++ nono/vm/mainbus_virt68k.cpp 2026/04/29 17:05:51 1.1.1.4 @@ -5,7 +5,7 @@ // // -// メインバス (virt68k) +// メインバス (virt-m68k) // // IODevice @@ -16,39 +16,35 @@ // | | | | +-- Luna1Mainbus // | | | | +-- Luna88kMainbus // | | | +-- NewsMainbus -// | | | | -// | | | | +----------------+ -// | | | +--| Virt68kMainbus | -// | | | +----------------+ +// | | | +// | | | +----------------+ +// | | +--| Virt68kMainbus | +// | | | +----------------+ // | | | // | | +-- X68kMainbus // | +-- X68kIODevice // +-- XPbusDevice #include "mainbus_virt68k.h" +#include "buserr.h" #include "interrupt.h" #include "mainapp.h" #include "mainram.h" +#include "monitor.h" #include "v68kio.h" // コンストラクタ Virt68kMainbus::Virt68kMainbus() + : inherited(OBJ_MAINBUS) { NEWDV(BusErr, new BusErrDevice()); NEWDV(Interrupt, new Virt68kInterrupt()); NEWDV(MainRAM, new MainRAMDevice()); NEWDV(V68kIO, new V68kIODevice()); - // $ff'000000 以降がデバイス領域。 // メインメモリは Init() で設定する。 - for (int i = 0; i < devtable.size() - 1; i++) { - devtable[i] = pBusErr.get(); - } - devtable[0xff] = pV68kIO.get(); - // 2MB ずつ 32bit 全域。 - acc.resize(2048); - monitor_accstat.SetSize(80, 2 + 32); + accstat_monitor->SetSize(80, 2 + 32); } // デストラクタ @@ -63,17 +59,86 @@ Virt68kMainbus::InitMainbus() // RAM は容量が確定した後のここで配置。 // 16MB 単位になっている。 auto mainram = dynamic_cast(pMainRAM.get()); - int ramsize_MB = mainram->GetSizeMB(); - for (int i = 0; i < ramsize_MB / 16; i++) { - devtable[i] = mainram; - } + ramsize = mainram->GetSize(); // アクセス状況用のマップを作成。 - InitAccStat(); + for (uint32 i = 0; i < 4096 / 16; i++) { + if (Decoder(i * 0x0100'0000) != pBusErr.get()) { + accstat_avail[i / 8] |= 0x80U >> (i % 8); + } + } return true; } +inline IODevice * +Virt68kMainbus::Decoder(uint32 addr) const +{ + if (__predict_true(addr < ramsize)) { + return pMainRAM.get(); + } else if (__predict_true(addr >= 0xff000000)) { + return pV68kIO.get(); + } else { + return pBusErr.get(); + } +} + +busdata +Virt68kMainbus::Read(busaddr addr) +{ + uint32 pa = addr.Addr(); + accstat_read[pa >> AccStat::SHIFT] = AccStat::READ; + IODevice *dev = Decoder(pa); + return dev->Read(addr); +} + +busdata +Virt68kMainbus::Write(busaddr addr, uint32 data) +{ + uint32 pa = addr.Addr(); + accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE; + IODevice *dev = Decoder(pa); + return dev->Write(addr, data); +} + +busdata +Virt68kMainbus::ReadBurst16(busaddr addr, uint32 *dst) +{ + uint32 pa = addr.Addr(); + IODevice *dev = Decoder(pa); + busdata r = dev->ReadBurst16(addr, dst); + if (__predict_true(r.IsBusErr() == false)) { + accstat_read[pa >> AccStat::SHIFT] = AccStat::READ; + } + return r; +} + +busdata +Virt68kMainbus::WriteBurst16(busaddr addr, const uint32 *src) +{ + uint32 pa = addr.Addr(); + IODevice *dev = Decoder(pa); + busdata r = dev->WriteBurst16(addr, src); + if (__predict_true(r.IsBusErr() == false)) { + accstat_read[pa >> AccStat::SHIFT] = AccStat::WRITE; + } + return r; +} + +busdata +Virt68kMainbus::Peek1(uint32 addr) +{ + IODevice *dev = Decoder(addr); + return dev->Peek1(addr); +} + +bool +Virt68kMainbus::Poke1(uint32 addr, uint32 data) +{ + IODevice *dev = Decoder(addr); + return dev->Poke1(addr, data); +} + // ブートページを切り替える。 void Virt68kMainbus::SwitchBootPage(bool isram)