--- nono/vm/opm.cpp 2026/04/29 17:05:13 1.1.1.5 +++ nono/vm/opm.cpp 2026/04/29 17:05:49 1.1.1.10 @@ -10,25 +10,30 @@ #include "opm.h" #include "adpcm.h" +#include "event.h" #include "fdc.h" #include "mpu.h" #include "scheduler.h" -// グローバル参照用 -OPMDevice *gOPM; - // コンストラクタ OPMDevice::OPMDevice() - : inherited("OPM") + : inherited(OBJ_OPM) { - devaddr = baseaddr; - devlen = 0x2000; } // デストラクタ OPMDevice::~OPMDevice() { - gOPM = NULL; +} + +// 初期化 +bool +OPMDevice::Init() +{ + adpcm = GetADPCMDevice(); + fdc = GetFDCDevice(); + + return true; } // リセット @@ -39,20 +44,19 @@ OPMDevice::ResetHard(bool poweron) busy_start = 0; busy_end = 0; - gFDC->SetForceReady(false); + fdc->SetForceReady(false); } -uint64 -OPMDevice::Read(uint32 offset) +busdata +OPMDevice::ReadPort(uint32 offset) { - uint8 data; - - gMPU->AddCycle(19); // InsideOut p.135 + busdata data; switch (offset) { case 0: - putlog(0, "Read $%06x (NOT IMPLEMENTED)", gMPU->GetPaddr()); - return 0; + putlog(0, "Read $%06x (NOT IMPLEMENTED)", mpu->GetPaddr()); + data = 0; + break; case 1: // OPM ステータスレジスタ data = 0; @@ -61,19 +65,26 @@ OPMDevice::Read(uint32 offset) } // タイマ関係の bit1, bit0 は未実装 - putlog(1, "STAT -> $%02x", data); - return data; + putlog(1, "STAT -> $%02x", data.Data()); + break; default: - __unreachable(); + VMPANIC("corrupted offset=%u", offset); + data = 0xff; + break; } + + // InsideOut p.135 + const busdata read_wait = busdata::Wait(19 * 40_nsec); + data |= read_wait; + + data |= BusData::Size1; + return data; } -uint64 -OPMDevice::Write(uint32 offset, uint32 data) +busdata +OPMDevice::WritePort(uint32 offset, uint32 data) { - gMPU->AddCycle(53); // InsideOut p.135 - - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); switch (offset) { case 0: @@ -104,7 +115,7 @@ OPMDevice::Write(uint32 offset, uint32 d // 時刻の起点は CPU 側の命令によって異なるはずだが // わからないので命令のぶんは無視しておく。 // 53 クロックのウェイトのほうは足す。 - busy_origin = now + 53 * gMPU->GetClock_nsec(); + busy_origin = now + 53 * mpu->GetClock_nsec(); // busy_start のほうはとりあえず 10 クロックにしておく。 busy_start = busy_origin + 10 * clk; @@ -112,35 +123,47 @@ OPMDevice::Write(uint32 offset, uint32 d switch (reg) { case 0x1b: - gADPCM->SetClock(data & 0x80); - gFDC->SetForceReady(data & 0x40); + adpcm->SetClock(data & 0x80); + fdc->SetForceReady(data & 0x40); // 他のビットは未対応 break; default: putlog(0, "Write $%06x <- $%02x (NOT IMPLEMENTED)", - gMPU->GetPaddr(), data); + mpu->GetPaddr(), data); break; } break; default: - __unreachable(); + VMPANIC("corrupted offset=%u", offset); + break; } - return 0; + // InsideOut p.135 + const busdata write_wait = busdata::Wait(53 * 40_nsec); + + busdata r = write_wait; + r |= BusData::Size1; + return r; } -uint64 -OPMDevice::Peek(uint32 offset) +busdata +OPMDevice::PeekPort(uint32 offset) { // XXX 未実装 return 0xff; } +bool +OPMDevice::PokePort(uint32 offset, uint32 data) +{ + return false; +} + // OPM ステータスレジスタの B (BUSY) ビット bool OPMDevice::IsBusy() const { - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); return (busy_start <= now && now < busy_end); }