--- nono/vm/xiospace.cpp 2026/04/29 17:04:32 1.1.1.2 +++ nono/vm/xiospace.cpp 2026/04/29 17:04:42 1.1.1.4 @@ -1,19 +1,20 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include +#include "xiospace.h" #include "areaset.h" #include "busio.h" #include "crtc.h" #include "dmac.h" #include "fdc.h" #include "gvram.h" -#include "iocon.h" +#include "ioctlr.h" #include "mfp.h" -#include "pluto.h" #include "pio.h" +#include "pluto.h" #include "printer.h" #include "ram.h" #include "romimg_x68k.h" @@ -24,32 +25,28 @@ #include "sram.h" #include "sysport.h" #include "tvram.h" -#include "vicon.h" +#include "videoctlr.h" #include "vm.h" -#include "xiospace.h" +#include // // X68030 のメイン空間 ($000000-$FFFFFF) 担当。 // // デバイス -std::unique_ptr areaset; -std::unique_ptr cgrom; -std::unique_ptr crtc; -std::unique_ptr fdc; -std::unique_ptr iplrom1; -std::unique_ptr iplrom2; -std::unique_ptr pluto; -std::unique_ptr ppi; -std::unique_ptr printer; -std::unique_ptr sprite; -std::unique_ptr sysport; +static std::unique_ptr areaset; +static std::unique_ptr fdc; +static std::unique_ptr pluto; +static std::unique_ptr ppi; +static std::unique_ptr printer; +static std::unique_ptr sprite; +static std::unique_ptr sysport; // 1つの 8KB ブロックを複数のデバイスで共有する場合 class MuxDevice : public IODevice { - typedef IODevice inherited; + using inherited = IODevice; public: MuxDevice(); virtual ~MuxDevice(); @@ -76,13 +73,14 @@ MuxDevice::~MuxDevice() { } -// デバイスを追加します。 -// ここに追加するデバイスは dev->devlen の指定が必須です。 +// デバイスを追加する。 +// ここに追加するデバイスは dev->devlen を指定すること。 void MuxDevice::AddDevice(IODevice *dev) { if (dev->devlen == 0) { - printf("MuxDevice::AddDevice: '%s' devlen not set!\n", dev->devname); + printf("MuxDevice::AddDevice: '%s' devlen not set!\n", + dev->devname.c_str()); exit(1); } devlist.push_back(dev); @@ -156,14 +154,6 @@ XIOSpaceDevice::XIOSpaceDevice() logname = "xiospace"; devname = "IOSpace"; - // メモリ - // 通常メイン RAM は bus から直接アクセスするが、ウェイトを入れたい - // 場合や上位8ビットに値が入っていて 24bit にミラーされたアドレスへの - // アクセスになる場合はここを通る。 - for (int i = 0; i < ram_size / 8192; i++) { - table[i] = gRAM.get(); - } - #define ADD_DEVICE(varname, clsname) do { \ varname.reset(new clsname); \ AddDevice(varname.get()); \ @@ -171,58 +161,79 @@ XIOSpaceDevice::XIOSpaceDevice() // デバイスクラス作成 (順序に注意) ADD_DEVICE(areaset, AreaSetDevice()); - ADD_DEVICE(cgrom, CGROMDevice()); - ADD_DEVICE(crtc, CRTCDevice()); - ADD_DEVICE(gDMAC, DMACDevice()); - ADD_DEVICE(fdc, FDCDevice()); + ADD_DEVICE(gCGROM, CGROMDevice()); + ADD_DEVICE(gCRTC, BusIO_W()); + ADD_DEVICE(gDMAC, BusIO_B()); + ADD_DEVICE(fdc, BusIO_EB()); ADD_DEVICE(gGVRAM, GVRAMDevice()); - ADD_DEVICE(gIOCon, IOConDevice()); - ADD_DEVICE(iplrom1, IPLROM1Device()); - ADD_DEVICE(iplrom2, IPLROM2Device()); - ADD_DEVICE(gMFP, MFPDevice()); + ADD_DEVICE(gIOCtlr, BusIO_EB()); + ADD_DEVICE(gIPLROM1, IPLROM1Device()); + ADD_DEVICE(gIPLROM2, IPLROM2Device()); + ADD_DEVICE(gMFP, BusIO_EB()); ADD_DEVICE(pluto, PlutoDevice()); ADD_DEVICE(ppi, BusIO_EB()); ADD_DEVICE(printer, PrinterDevice()); - ADD_DEVICE(gRTC, RP5C15Device()); - ADD_DEVICE(gSCC, SCCDevice()); + ADD_DEVICE(gRTC, BusIO_EB()); + ADD_DEVICE(gSCC, BusIO_EB()); + ADD_DEVICE(gSRAM, SRAMDevice()); // Required by SPC ADD_DEVICE(gSPC, BusIO_X68kSPC()); ADD_DEVICE(sprite, SpriteDevice()); - ADD_DEVICE(gSRAM, SRAMDevice()); - ADD_DEVICE(sysport, SysportDevice()); + ADD_DEVICE(sysport, BusIO_FB()); ADD_DEVICE(gTVRAM, TVRAMDevice()); - ADD_DEVICE(gVicon, ViconDevice()); + ADD_DEVICE(gVideoCtlr, BusIO_W()); +} + +// デストラクタ +XIOSpaceDevice::~XIOSpaceDevice() +{ +} + +bool +XIOSpaceDevice::Init() +{ + // RAM のみ RamDevice::Init() で ram_size が決定してから行う。 + for (int i = 0; i < ram_size / 8192; i++) { + table[i] = gRAM.get(); + } + + // 必要なデバイスは全部埋めたので、この時点で nullptr なエントリを + // buserr に差し替える。 + IODevice *buserr = gVM->GetBusErrDevice(); + for (auto&& d : table) { + if (d == nullptr) { + d = buserr; + } + } // デバッグ表示 if (0) { for (int i = 0; i < 512; i++) { printf("[%3d] $%06x ", i, 0xc00000 + i * 8192); - if (table[i] == nullptr) { - printf("null\n"); - } else if (dynamic_cast(table[i])) { + assert(table[i]); + if (dynamic_cast(table[i])) { printf("MuxDevice\n"); - } else if (dynamic_cast(table[i])) { - printf("%s\n", table[i]->devname); + } else { + printf("%s\n", table[i]->devname.c_str()); } } } -} -// デストラクタ -XIOSpaceDevice::~XIOSpaceDevice() -{ + return true; } // デバイステーブルに dev を追加する。 -// ここに追加するデバイスは dev->devlen の指定が必須です。 +// ここに追加するデバイスは dev->devlen を指定すること。 void XIOSpaceDevice::AddDevice(IODevice *dev) { if (dev->devaddr == 0) { - printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n", dev->devname); + printf("XIOSpaceDevice:AddDevice: '%s' devaddr not set!\n", + dev->devname.c_str()); exit(1); } if (dev->devlen == 0) { - printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n", dev->devname); + printf("XIOSpaceDevice:AddDevice: '%s' devlen not set!\n", + dev->devname.c_str()); exit(1); } @@ -230,13 +241,16 @@ XIOSpaceDevice::AddDevice(IODevice *dev) for (int i = idx; i < idx + (dev->devlen + 8191) / 8192; i++) { if (table[i] == nullptr) { table[i] = dev; - } else if (typeid(*table[i]) == typeid(MuxDevice)) { - (static_cast(table[i]))->AddDevice(dev); } else { - MuxDevice *muxdev = new MuxDevice(); - muxdev->AddDevice(table[i]); - muxdev->AddDevice(dev); - table[i] = muxdev; + MuxDevice *mux = dynamic_cast(table[i]); + if (mux) { + mux->AddDevice(dev); + } else { + MuxDevice *muxdev = new MuxDevice(); + muxdev->AddDevice(table[i]); + muxdev->AddDevice(dev); + table[i] = muxdev; + } } } } @@ -246,10 +260,6 @@ XIOSpaceDevice::Read8(uint32 addr) { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Read8(addr); } @@ -258,10 +268,6 @@ XIOSpaceDevice::Read16(uint32 addr) { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Read16(addr); } @@ -270,10 +276,6 @@ XIOSpaceDevice::Read32(uint32 addr) { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Read32(addr); } @@ -282,10 +284,6 @@ XIOSpaceDevice::Write8(uint32 addr, uint { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Write8(addr, data); } @@ -294,10 +292,6 @@ XIOSpaceDevice::Write16(uint32 addr, uin { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Write16(addr, data); } @@ -306,10 +300,6 @@ XIOSpaceDevice::Write32(uint32 addr, uin { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Write32(addr, data); } @@ -318,9 +308,5 @@ XIOSpaceDevice::Peek8(uint32 addr) { addr &= 0x00ffffff; IODevice *d = SearchDevice(addr); - // BusErrDevice 導入すればこの if は不要 - if (d == nullptr) { - return (uint64)-1; - } return d->Peek8(addr); }