--- nono/vm/dmac.h 2026/04/29 17:05:14 1.1.1.11 +++ nono/vm/dmac.h 2026/04/29 17:06:01 1.1.1.19 @@ -11,11 +11,16 @@ #pragma once #include "device.h" +#include "bus.h" #include "fixedqueue.h" -#include "monitor.h" -#include "event.h" #include +class ADPCMDevice; +class FDCDevice; +class InterruptDevice; +class MainbusDevice; +class Syncer; + struct DMAC { static const uint32 CSR = 0x00; // .B @@ -100,9 +105,10 @@ struct DMAC static const uint32 SIZE_16BIT = 1; // 16bit static const uint32 SIZE_32BIT = 2; // 32bit static const uint32 SIZE_8BIT_UNPK = 3; // 8bit UnPacked - static const uint32 CHAIN_NOCHAIN = 0; // Chain operation is disabled + static const uint32 CHAIN_DISABLED = 0; // Chain operation is disabled + static const uint32 CHAIN_reserved = 1; // (Undefined, reserved) static const uint32 CHAIN_ARRAY = 2; // Array Chaining - static const uint32 CHAIN_LINK = 3; // Linked Array Chaining + static const uint32 CHAIN_LINKARRAY = 3; // Linked Array Chaining static const uint32 REQG_AUTO_LIM = 0; // Auto Request (Limited) static const uint32 REQG_AUTO_MAX = 1; // AUto Request (Max) static const uint32 REQG_EXTERNAL = 2; // External Request @@ -140,9 +146,13 @@ struct DMAC }; // 各チャンネル -class DMACChan +class DMACChan : public Device { + using inherited = Device; public: + DMACChan(int ch_, const char *desc_); + ~DMACChan() override; + // 二次変数など int ch; // チャンネル番号 const char *desc; // チャンネルの用途(モニタ表示用) @@ -217,10 +227,10 @@ class DMACChan uint32 bar; uint8 niv; uint8 eiv; - uint8 mfc; uint8 cpr; - uint8 dfc; - uint8 bfc; + busaddr mfc; + busaddr dfc; + busaddr bfc; void SetNIV(uint8); void SetEIV(uint8); void SetMFC(uint8); @@ -229,13 +239,13 @@ class DMACChan void SetBFC(uint8); // 転送シーケンス - std::vector seq {}; + std::vector seq {}; int seq_index {}; // 転送リトライカウンタ。 // 実際には (SPC からの) DTACK を待つのだが、 // 待つのは大変なのでこちらでポーリングしている。 - int retry {}; + uint retry {}; // 転送中データ FixedQueue data; @@ -245,7 +255,7 @@ class DMACDevice : public IODevice { using inherited = IODevice; - static const int baseaddr = 0xe84000; + static const uint32 baseaddr = 0xe84000; // 転送シーケンス enum { @@ -258,59 +268,66 @@ class DMACDevice : public IODevice WR_M16, WR_D8, WR_D16, + SEQ_MAX, }; public: DMACDevice(); - virtual ~DMACDevice() override; + ~DMACDevice() override; + bool Init() override; void ResetHard(bool poweron) override; - uint64 Read8(uint32 addr) override; - uint64 Read16(uint32 addr) override; - uint64 Write8(uint32 addr, uint32 data) override; - uint64 Write16(uint32 addr, uint32 data) override; - uint64 Peek8(uint32 addr) override; + busdata Read(busaddr addr) override; + busdata Write(busaddr addr, uint32 data) override; + busdata Peek1(uint32 addr) override; // 外部デバイスが REQ 信号を操作する - void AssertREQ(int ch); - void NegateREQ(int ch); + void AssertREQ(uint ch); + void NegateREQ(uint ch); // 割り込みアクノリッジ - int InterruptAcknowledge(); + busdata InterruptAcknowledge(); - protected: - // BusIO インタフェース - static const uint NPORT = 256; - uint64 Read(uint32 offset); - uint64 Write(uint32 offset, uint32 data); - uint64 Peek(uint32 offset); + // ユーザ空間制御 + void SetUdevice(uint32 start, uint32 end, bool accessible); private: - DECLARE_MONITOR_CALLBACK(MonitorUpdate); + DECLARE_MONITOR_SCREEN(MonitorScreen); void MonitorReg4(TextScreen&, int x, int y, uint32 reg, const char * const *names); + busdata WriteByte(DMACChan *chan, uint32 n, uint32 data); + busdata WriteWord(DMACChan *chan, uint32 n, uint32 data); + // チャンネル操作 void WriteCSR(DMACChan *chan, uint32 data); void WriteCCR(DMACChan *chan, uint32 data, uint8 up); void WriteGCR(uint8 data); + // ACT ビットの状態を変更 + void ChangeACT(DMACChan *, bool); + // 割り込み信号線の状態を変更 void ChangeInterrupt(); // 転送 void StartTransfer(DMACChan *chan); void AbortTransfer(DMACChan *chan); + std::string MakeStartLog(DMACChan *chan); + bool LoadLinkArray(DMACChan *chan); DMACChan *SelectChannel(); // 転送イベントコールバック - void StartCallback(Event& ev); - void TransferCallback(Event& ev); + void StartCallback(Event *); + void TransferCallback(Event *); + + // ログ出力 + void TransferLog(DMACChan *, uint op, busaddr addr, busdata r, uint64 data); // 転送中エラー - void TransferError(DMACChan *, int op, uint64); + void TransferError(DMACChan *, uint op, busdata r, uint32 data); // エラー発生 void Error(DMACChan *chan, uint8 errcode); @@ -318,15 +335,34 @@ class DMACDevice : public IODevice void AssertACK(DMACChan *); void NegateACK(DMACChan *); + // メインメモリアクセス + busdata ReadMem(busaddr addr); + busdata ReadMem4(busaddr addr); + busdata WriteMem(busaddr addr, uint32 data); + // レジスタ - std::array channel {}; + std::array, 4> channels {}; uint8 gcr; - Event event { this }; + // ユーザ空間制御 + std::array useraccess {}; + + ADPCMDevice *adpcm {}; + FDCDevice *fdc {}; + InterruptDevice *interrupt {}; + MainbusDevice *mainbus {}; + Syncer *syncer {}; + + Event *event {}; - Monitor monitor { this }; + Monitor *monitor {}; static const char * const errnames[]; + static const char * const regname1[0x40]; + static const char * const regname2[0x20]; + static const char * const seqname[SEQ_MAX]; }; -extern DMACDevice *gDMAC; +inline DMACDevice *GetDMACDevice() { + return Object::GetObject(OBJ_DMAC); +}