--- nono/vm/adpcm.cpp 2026/04/29 17:05:13 1.1 +++ nono/vm/adpcm.cpp 2026/04/29 17:05:24 1.1.1.3 @@ -14,16 +14,10 @@ #include "pio.h" #include "scheduler.h" -// グローバル参照用 -ADPCMDevice *gADPCM; - // コンストラクタ ADPCMDevice::ADPCMDevice() - : inherited("ADPCM") + : inherited(OBJ_ADPCM) { - devaddr = baseaddr; - devlen = 0x2000; - event.func = ToEventCallback(&ADPCMDevice::EventCallback); event.Regist("ADPCM"); } @@ -31,7 +25,20 @@ ADPCMDevice::ADPCMDevice() // デストラクタ ADPCMDevice::~ADPCMDevice() { - gADPCM = NULL; +} + +// 初期化 +bool +ADPCMDevice::Init() +{ + if (inherited::Init() == false) { + return false; + } + + dmac = GetDMACDevice(); + ppi = GetPPIDevice(); + + return true; } // リセット @@ -46,12 +53,10 @@ ADPCMDevice::ResetHard(bool poweron) div = 512; } -uint64 +busdata ADPCMDevice::Read(uint32 offset) { - uint8 data; - - gMPU->AddCycle(18); // InsideOut p.135 + busdata data; switch (offset) { case 0: // STAT @@ -59,24 +64,26 @@ ADPCMDevice::Read(uint32 offset) if (playing) { data |= STAT_PLAY; } - putlog(1, "STAT -> $%02x", data); + putlog(1, "STAT -> $%02x", data.Data()); break; case 1: // DATA - putlog(0, "Read $%06x (NOT IMPLEMENTED)", gMPU->GetPaddr()); + putlog(0, "Read $%06x (NOT IMPLEMENTED)", mpu->GetPaddr()); data = 0xff; break; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); } + // InsideOut p.135 + const busdata wait = busdata::Wait(18 * 40_nsec); + data |= wait; + return data; } -uint64 +busdata ADPCMDevice::Write(uint32 offset, uint32 data) { - gMPU->AddCycle(22); // InsideOut p.135 - switch (offset) { case 0: // CMD putlog(1, "CMD <- $%02x", data); @@ -99,13 +106,15 @@ ADPCMDevice::Write(uint32 offset, uint32 } break; default: - __unreachable(); + VMPANIC("corrupted offset=%d", offset); } - return 0; + // InsideOut p.135 + const busdata wait = busdata::Wait(22 * 40_nsec); + return wait; } -uint64 +busdata ADPCMDevice::Peek(uint32 offset) { // XXX 未実装 @@ -118,7 +127,8 @@ ADPCMDevice::StartPlay() { // PPI で設定されているサンプリングレートをここで読み出す。 // XXX パンは未対応 - switch (gPPI->GetADPCMRate()) { + int rate = ppi->GetADPCMRate(); + switch (rate) { case 0: div = 1024; break; @@ -130,14 +140,14 @@ ADPCMDevice::StartPlay() div = 512; break; default: - __unreachable(); + VMPANIC("corrupted ADPCM rate=%d", rate); } playing = true; - gDMAC->AssertREQ(3); + dmac->AssertREQ(3); event.time = div / clk; - gScheduler->StartEvent(event); + scheduler->StartEvent(event); } // イベント @@ -146,7 +156,7 @@ ADPCMDevice::EventCallback(Event& ev) { // XXX 適当 if (playing) { - gDMAC->AssertREQ(3); + dmac->AssertREQ(3); } } @@ -156,7 +166,7 @@ ADPCMDevice::AssertDACK(bool tc_) { dack = true; // DRQ を下げる - gDMAC->NegateREQ(0); + dmac->NegateREQ(0); } // DACK 信号をネゲートする (DMAC から呼ばれる)