--- nono/vm/dmac.h 2026/04/29 17:04:32 1.1.1.2 +++ nono/vm/dmac.h 2026/04/29 17:05:11 1.1.1.10 @@ -1,12 +1,19 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// DMAC (HD63450) // #pragma once #include "device.h" -#include "scheduler.h" +#include "monitor.h" +#include "event.h" +#include struct DMAC { @@ -107,6 +114,7 @@ struct DMAC int ch; // チャンネル番号 const char *desc; // チャンネルの用途(モニタ表示用) DMACDevice *parent; + uint8 priority; // 現在の実効プライオリティ // レジスタ @@ -115,6 +123,10 @@ struct DMAC bool active; // ACT bool pcl; // PCL の状態 (High が true) bool prev_pcl; // 前回の PCL の状態 (High が true) + bool IsINTR() const { // CSR の割り込み要因が立っていれば true + // XXX PCT は未対応 + return (csr & (CSR_COC | CSR_BTC | CSR_NDT | CSR_ERR)); + } uint8 cer; uint8 dcr; @@ -137,7 +149,6 @@ struct DMAC uint32 GetDAC() const { return (scr & 3); } uint8 ccr; - bool int_enable; // INT: 割り込み許可なら true uint16 mtc; uint32 mar; @@ -153,49 +164,73 @@ struct DMAC uint8 PeekCSR() const; void WriteCSR(uint32 data); - uint8 PeekCCR() const; void WriteCCR(uint32 data); // 転送開始 void StartTransfer(); - // 割り込み - void SetINT(uint32 val); } chan[4]; // 全体 uint8 gcr; }; -class DMACDevice - : public IODevice +class DMACDevice : public IODevice { - typedef IODevice inherited; + using inherited = IODevice; static const int baseaddr = 0xe84000; public: DMACDevice(); - virtual ~DMACDevice(); - - virtual uint64 Read8(uint32 addr); - virtual uint64 Write8(uint32 addr, uint32 data); - virtual uint64 Peek8(uint32 addr); + virtual ~DMACDevice() override; - virtual bool MonitorUpdate(); + void ResetHard(bool poweron) override; // 転送 + void StartTransfer(); void AbortTransfer(DMAC::Channel *chan); - void Transfer(int arg); - int64 TransferM8toD8(DMAC::Channel *chan); - int64 TransferD8toM8(DMAC::Channel *chan); + + // 割り込みアクノリッジ + int InterruptAcknowledge(); + + protected: + // BusIO インタフェース + static const uint NPORT = 256; + uint64 Read(uint32 offset); + uint64 Write(uint32 offset, uint32 data); + uint64 Peek(uint32 offset); private: - void MonitorReg4(int x, int y, uint32 reg, const char * const *names); + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + + void MonitorReg4(TextScreen&, + int x, int y, uint32 reg, const char * const *names); + + // 割り込み信号線の状態を変更 + void ChangeInterrupt(); + + // 転送イベントコールバック + void StartCallback(Event& ev); + void ReadCallback(Event& ev); + void WriteCallback(Event& ev); + void DoneCallback(Event& ev); + + // 転送中エラー + void Error(uint64); struct DMAC dmac {}; - Event event[4] {}; + + Event event { this }; + + DMAC::Channel *xfer_chan {}; // 現在転送中のチャンネル + uint32 xfer_src; // 転送中ソースアドレス + uint32 xfer_dst; // 転送中ディスティネーションアドレス + uint32 xfer_data; // 転送中データ + int xfer_retry {}; // 転送リトライ + + Monitor monitor { this }; static const char * const errnames[]; }; -extern std::unique_ptr gDMAC; +extern DMACDevice *gDMAC;