--- nono/vm/dmac.cpp 2026/04/29 17:05:33 1.1.1.15 +++ nono/vm/dmac.cpp 2026/04/29 17:05:38 1.1.1.16 @@ -16,6 +16,7 @@ #include "monitor.h" #include "mpu.h" #include "scheduler.h" +#include "syncer.h" // time 時間後に呼び出すコールバックをセットする。 // func の書式が面倒なのを省略して書きたいため。 @@ -67,14 +68,11 @@ DMACDevice::~DMACDevice() bool DMACDevice::Init() { - if (inherited::Init() == false) { - return false; - } - adpcm = GetADPCMDevice(); fdc = GetFDCDevice(); interrupt = GetInterruptDevice(); mainbus = GetMainbusDevice(); + syncer = GetSyncer(); event.SetName("DMAC"); scheduler->RegistEvent(event); @@ -121,6 +119,7 @@ DMACDevice::ResetHard(bool poweron) chan->priority = 0; } + syncer->RequestDMACActive(false); ChangeInterrupt(); // イベントを停止 @@ -1045,6 +1044,22 @@ DMACDevice::WriteCCR(DMACChan *chan, uin ChangeInterrupt(); } +// CSR.ACT ビットの状態を変更。 +void +DMACDevice::ChangeACT(DMACChan *chan, bool active) +{ + chan->active = active; + + // チャンネルの ACT を変更した結果、 + // トータルでアクティブかどうかを Syncer に通知する。 + bool dmac_active = + channel[0].active || + channel[1].active || + channel[2].active || + channel[3].active; + syncer->RequestDMACActive(dmac_active); +} + // 転送開始 void DMACDevice::StartTransfer(DMACChan *chan) @@ -1057,7 +1072,7 @@ DMACDevice::StartTransfer(DMACChan *chan } // ACT を立てたら STR を下げる。 - chan->active = true; + ChangeACT(chan, true); chan->str = false; // XXX あとで移動する @@ -1481,7 +1496,7 @@ DMACDevice::TransferCallback(Event& ev) // すべての転送完了か if (__predict_false(chan->mtc == 0)) { chan->csr |= DMAC::CSR_COC; - chan->active = false; + ChangeACT(chan, false); ChangeInterrupt(); } @@ -1639,7 +1654,7 @@ DMACDevice::Error(DMACChan *chan, uint8 // データシート p.43 chan->cer = errcode; chan->csr |= DMAC::CSR_COC | DMAC::CSR_ERR; - chan->active = false; + ChangeACT(chan, false); chan->str = false; chan->cnt = false; ChangeInterrupt(); @@ -1732,7 +1747,8 @@ DMACDevice::AbortTransfer(DMACChan *chan chan->str = false; chan->cnt = false; - chan->active = false; + ChangeACT(chan, false); + chan->cer = DMAC::CER_SOFT_ABORT; // ERR ビットが立つと SAB をクリアする chan->csr |= DMAC::CSR_ERR;