Annotation of nono/vm/dmac.h, revision 1.1.1.11

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.10  root        7: //
                      8: // DMAC (HD63450)
                      9: //
                     10: 
1.1       root       11: #pragma once
                     12: 
                     13: #include "device.h"
1.1.1.11! root       14: #include "fixedqueue.h"
1.1.1.8   root       15: #include "monitor.h"
1.1.1.10  root       16: #include "event.h"
1.1.1.9   root       17: #include <array>
1.1       root       18: 
                     19: struct DMAC
                     20: {
1.1.1.2   root       21:        static const uint32 CSR = 0x00; // .B
                     22:        static const uint32 CER = 0x01; // .B
                     23:        static const uint32 DCR = 0x04; // .B
                     24:        static const uint32 OCR = 0x05; // .B
                     25:        static const uint32 SCR = 0x06; // .B
                     26:        static const uint32 CCR = 0x07; // .B
                     27:        static const uint32 MTC = 0x0a; // .W
                     28:        static const uint32 MAR = 0x0c; // .L
                     29:        static const uint32 DAR = 0x14; // .L
                     30:        static const uint32 BTC = 0x1a; // .W
                     31:        static const uint32 BAR = 0x1c; // .L
                     32:        static const uint32 NIV = 0x25; // .B
                     33:        static const uint32 EIV = 0x27; // .B
                     34:        static const uint32 MFC = 0x29; // .B
                     35:        static const uint32 CPR = 0x2d; // .B
                     36:        static const uint32 DFC = 0x31; // .B
                     37:        static const uint32 BFC = 0x39; // .B
                     38:        static const uint32 GCR = 0x3f; // .B (ch#3のみ)
                     39: 
1.1.1.11! root       40:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !            41:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            42:        // CSR | COC | BTC | NDT | ERR | ACT | DIT | PCT | PCS |
        !            43:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
1.1.1.2   root       44:        //
                     45:        static const uint32 CSR_COC = 0x80;     // Channel Operation Complete
                     46:        static const uint32 CSR_BTC = 0x40;     // Block Transfer Complete
                     47:        static const uint32 CSR_NDT = 0x20;     // Normal Device Termination
                     48:        static const uint32 CSR_ERR = 0x10;     // Error Bit
                     49:        static const uint32 CSR_ACT = 0x08;     // Channel Active
1.1.1.11! root       50:        static const uint32 CSR_DIT = 0x04;     // DONE Input Transition
1.1.1.2   root       51:        static const uint32 CSR_PCT = 0x02;     // PCL Transition
                     52:        static const uint32 CSR_PCS = 0x01;     // PCL Input Line State
                     53: 
1.1.1.11! root       54:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !            55:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            56:        // CER |        0        |         Error Code          |
        !            57:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            58:        //
1.1.1.2   root       59:        static const uint32 CER_NO_ERROR        = 0x00; // No Error
                     60:        static const uint32 CER_CONFIG          = 0x01; // Configuration Error
1.1.1.11! root       61:        static const uint32 CER_TIMING          = 0x02; // Operation Timing Error
1.1.1.2   root       62:        static const uint32 CER_ADDR_MAR        = 0x05; // Address error in MAR
                     63:        static const uint32 CER_ADDR_DAR        = 0x06; // Address error in DAR
                     64:        static const uint32 CER_ADDR_BAR        = 0x07; // Address error in BAR
                     65:        static const uint32 CER_BUS_MAR         = 0x09; // Bus error in MAR
                     66:        static const uint32 CER_BUS_DAR         = 0x0a; // Bus error in DAR
                     67:        static const uint32 CER_BUS_BAR         = 0x0b; // Bus error in BAR
                     68:        static const uint32 CER_COUNT_MTC       = 0x0d; // Count error in MTC
                     69:        static const uint32 CER_COUNT_BTC       = 0x0f; // Count error in BTC
                     70:        static const uint32 CER_EXT_ABORT       = 0x10; // External Abort
                     71:        static const uint32 CER_SOFT_ABORT      = 0x11; // Software Abort
                     72: 
1.1.1.11! root       73:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !            74:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            75:        // DCR |    XRM    |    DTYP   | DPS |  0  |    PCL    |
        !            76:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            77:        //
        !            78:        static const uint32 XRM_BURST   = 0;            // Burst Transfer
        !            79:        static const uint32 XRM_CYCLE_WO_HOLD = 2;      // Cycle Steal without Hold
        !            80:        static const uint32 XRM_CYCLE_WITH_HOLD = 3;// Cycle Steal with Hold
        !            81:        static const uint32 DTYP_68000  = 0;            // 68000 devices
        !            82:        static const uint32 DTYP_6800   = 1;            // 6800 devices
        !            83:        static const uint32 DTYP_ACK    = 2;            // Devices with ACK
        !            84:        static const uint32 DTYP_ACK_REDY = 3;          // Devices with ACK+READY
        !            85:        static const uint32 DPS_8BIT    = 0;            // 8bit port
        !            86:        static const uint32 DPS_16BIT   = 1;            // 16bit port
        !            87:        static const uint32 PCL_STATUS  = 0;            // Status Input
        !            88:        static const uint32 PCL_STATUS_INTR = 1;        // Status Input with Interrupt
        !            89:        static const uint32 PCL_PULSE   = 2;            // Start Pulse
        !            90:        static const uint32 PCL_ABORT   = 3;            // Abort Input
        !            91: 
        !            92:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !            93:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            94:        // OCR | DIR |  0  |    SIZE   |   CHAIN   |    REQG   |
        !            95:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !            96:        //
        !            97:        static const uint32 DIR_MtoD = 0;                       // Memory to Device
        !            98:        static const uint32 DIR_DtoM = 1;                       // Device to Memory
        !            99:        static const uint32 SIZE_8BIT_PACK = 0;         // 8bit (Packed)
        !           100:        static const uint32 SIZE_16BIT = 1;                     // 16bit
        !           101:        static const uint32 SIZE_32BIT = 2;                     // 32bit
        !           102:        static const uint32 SIZE_8BIT_UNPK = 3;         // 8bit UnPacked
        !           103:        static const uint32 CHAIN_NOCHAIN = 0;          // Chain operation is disabled
        !           104:        static const uint32 CHAIN_ARRAY = 2;            // Array Chaining
        !           105:        static const uint32 CHAIN_LINK = 3;                     // Linked Array Chaining
        !           106:        static const uint32 REQG_AUTO_LIM = 0;          // Auto Request (Limited)
        !           107:        static const uint32 REQG_AUTO_MAX = 1;          // AUto Request (Max)
        !           108:        static const uint32 REQG_EXTERNAL = 2;          // External Request
        !           109:        static const uint32 REQG_AUTOFIRST = 3;         // Auto first then ext.
        !           110: 
        !           111:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !           112:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           113:        // SCR |           0           |    MAC    |    DAC    |
        !           114:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           115:        //
1.1.1.2   root      116:        static const uint32 SCR_NO_COUNT        = 0;    // Does not count
                    117:        static const uint32 SCR_COUNT_UP        = 1;    // Count up
                    118:        static const uint32 SCR_COUNT_DOWN      = 2;    // Count down
                    119: 
1.1.1.11! root      120:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !           121:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           122:        // CCR | STR | CNT | HLT | SAB | INT |        0        |
        !           123:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           124:        //
1.1.1.2   root      125:        static const uint32 CCR_STR = 0x80;     // Start Operation
                    126:        static const uint32 CCR_CNT = 0x40;     // Continue Operation
                    127:        static const uint32 CCR_HLT = 0x20;     // Halt Operation
                    128:        static const uint32 CCR_SAB = 0x10;     // Software Abort
                    129:        static const uint32 CCR_INT = 0x08;     // Interrupt Enable
1.1       root      130: 
1.1.1.11! root      131:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !           132:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           133:        // CPR |                 0                 |    CP     |
        !           134:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           135: 
        !           136:        //       b7    b6    b5    b4    b3    b2    b1    b0
        !           137:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           138:        // GCR |           0           |    BT     |    BR     |
        !           139:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
        !           140: };
1.1       root      141: 
1.1.1.11! root      142: // 各チャンネル
        !           143: class DMACChan
        !           144: {
        !           145:  public:
        !           146:        // 二次変数など
        !           147:        int ch;                         // チャンネル番号
        !           148:        const char *desc;       // チャンネルの用途(モニタ表示用)
        !           149:        uint8 priority;         // 現在の実効プライオリティ
        !           150:        bool req;                       // REQ#n 信号
        !           151: 
        !           152:        // レジスタ
        !           153: 
        !           154:        // CSR
        !           155:        uint8 csr;                      // COC,BTC,NDT,ERR を保持
        !           156:        bool active;            // ACT
        !           157:        bool pcl_pin;           // PCL 信号線の状態 (High が true)
        !           158:        bool pcl_prev;          // 前回の PCL の状態 (High が true)
        !           159:        uint8 GetCSR() const;
        !           160:        bool IsINTR() const {   // CSR の割り込み要因が立っていれば true
        !           161:                // XXX PCT は未対応
        !           162:                return csr;
        !           163:        }
        !           164: 
        !           165:        uint8 cer;
        !           166: 
        !           167:        // DCR
        !           168:        uint xrm;
        !           169:        uint dtyp;
        !           170:        uint dps;
        !           171:        uint dcr_pcl;
        !           172:        uint8 GetDCR() const;
        !           173:        void SetDCR(uint8);
        !           174:        uint GetXRM()   const { return xrm; }
        !           175:        uint GetDTYP()  const { return dtyp; }
        !           176:        uint GetDPS()   const { return dps; }
        !           177:        uint GetPCL()   const { return dcr_pcl; }
        !           178: 
        !           179:        // OCR
        !           180:        uint dir;
        !           181:        uint size;
        !           182:        uint chain;
        !           183:        uint reqg;
        !           184:        uint8 GetOCR() const;
        !           185:        void SetOCR(uint8);
        !           186:        uint32 GetDIR()   const { return dir; }
        !           187:        uint32 GetSIZE()  const { return size; }
        !           188:        uint32 GetCHAIN() const { return chain; }
        !           189:        uint32 GetREQG()  const { return reqg; }
        !           190:        bool IsChain() const { return GetCHAIN() & 0x02; }
        !           191:        bool IsSingleAddress() const { return GetREQG() & 0x02; }
        !           192: 
        !           193:        // SCR
        !           194:        // XXX 名前が衝突してるのは後からなんとかする
        !           195:        uint scr_mac;
        !           196:        uint scr_dac;
        !           197:        uint8 GetSCR() const;
        !           198:        void SetSCR(uint8);
        !           199:        uint32 GetMAC()   const { return scr_mac; }
        !           200:        uint32 GetDAC()   const { return scr_dac; }
        !           201:        int mac;
        !           202:        int dac;
        !           203: 
        !           204:        // CCR
        !           205:        bool str;
        !           206:        bool cnt;
        !           207:        bool hlt;
        !           208:        bool sab;
        !           209:        bool int_enable;
        !           210:        uint8 GetCCR() const;
        !           211:        void SetCCR(uint8);
        !           212: 
        !           213:        uint16 mtc;
        !           214:        uint32 mar;
        !           215:        uint32 dar;
        !           216:        uint16 btc;
        !           217:        uint32 bar;
        !           218:        uint8 niv;
        !           219:        uint8 eiv;
        !           220:        uint8 mfc;
        !           221:        uint8 cpr;
        !           222:        uint8 dfc;
        !           223:        uint8 bfc;
        !           224:        void SetNIV(uint8);
        !           225:        void SetEIV(uint8);
        !           226:        void SetMFC(uint8);
        !           227:        void SetCPR(uint8);
        !           228:        void SetDFC(uint8);
        !           229:        void SetBFC(uint8);
        !           230: 
        !           231:        // 転送シーケンス
        !           232:        std::vector<int> seq {};
        !           233:        int seq_index {};
        !           234: 
        !           235:        // 転送リトライカウンタ。
        !           236:        // 実際には (SPC からの) DTACK を待つのだが、
        !           237:        // 待つのは大変なのでこちらでポーリングしている。
        !           238:        int retry {};
        !           239: 
        !           240:        // 転送中データ
        !           241:        FixedQueue<uint8, 2> data;
1.1       root      242: };
                    243: 
1.1.1.8   root      244: class DMACDevice : public IODevice
1.1       root      245: {
1.1.1.3   root      246:        using inherited = IODevice;
1.1       root      247: 
                    248:        static const int baseaddr = 0xe84000;
                    249: 
1.1.1.11! root      250:        // 転送シーケンス
        !           251:        enum {
        !           252:                NOP = 0,
        !           253:                RD_M8,
        !           254:                RD_M16,
        !           255:                RD_D8,
        !           256:                RD_D16,
        !           257:                WR_M8,
        !           258:                WR_M16,
        !           259:                WR_D8,
        !           260:                WR_D16,
        !           261:        };
        !           262: 
1.1       root      263:  public:
                    264:        DMACDevice();
1.1.1.6   root      265:        virtual ~DMACDevice() override;
1.1       root      266: 
1.1.1.10  root      267:        void ResetHard(bool poweron) override;
1.1.1.2   root      268: 
1.1.1.11! root      269:        uint64 Read8(uint32 addr) override;
        !           270:        uint64 Read16(uint32 addr) override;
        !           271:        uint64 Write8(uint32 addr, uint32 data) override;
        !           272:        uint64 Write16(uint32 addr, uint32 data) override;
        !           273:        uint64 Peek8(uint32 addr) override;
        !           274: 
        !           275:        // 外部デバイスが REQ 信号を操作する
        !           276:        void AssertREQ(int ch);
        !           277:        void NegateREQ(int ch);
1.1.1.2   root      278: 
1.1.1.6   root      279:        // 割り込みアクノリッジ
                    280:        int InterruptAcknowledge();
                    281: 
1.1.1.3   root      282:  protected:
                    283:        // BusIO インタフェース
                    284:        static const uint NPORT = 256;
1.1.1.7   root      285:        uint64 Read(uint32 offset);
                    286:        uint64 Write(uint32 offset, uint32 data);
                    287:        uint64 Peek(uint32 offset);
1.1.1.3   root      288: 
1.1       root      289:  private:
1.1.1.8   root      290:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
1.1.1.10  root      291: 
1.1.1.4   root      292:        void MonitorReg4(TextScreen&,
                    293:                int x, int y, uint32 reg, const char * const *names);
1.1       root      294: 
1.1.1.11! root      295:        // チャンネル操作
        !           296:        void WriteCSR(DMACChan *chan, uint32 data);
        !           297:        void WriteCCR(DMACChan *chan, uint32 data, uint8 up);
        !           298:        void WriteGCR(uint8 data);
        !           299: 
1.1.1.6   root      300:        // 割り込み信号線の状態を変更
                    301:        void ChangeInterrupt();
                    302: 
1.1.1.11! root      303:        // 転送
        !           304:        void StartTransfer(DMACChan *chan);
        !           305:        void AbortTransfer(DMACChan *chan);
        !           306:        DMACChan *SelectChannel();
        !           307: 
1.1.1.10  root      308:        // 転送イベントコールバック
                    309:        void StartCallback(Event& ev);
1.1.1.11! root      310:        void TransferCallback(Event& ev);
1.1.1.10  root      311: 
                    312:        // 転送中エラー
1.1.1.11! root      313:        void TransferError(DMACChan *, int op, uint64);
1.1.1.10  root      314: 
1.1.1.11! root      315:        // エラー発生
        !           316:        void Error(DMACChan *chan, uint8 errcode);
1.1.1.10  root      317: 
1.1.1.11! root      318:        void AssertACK(DMACChan *);
        !           319:        void NegateACK(DMACChan *);
1.1.1.10  root      320: 
1.1.1.11! root      321:        // レジスタ
        !           322:        std::array<DMACChan, 4> channel {};
        !           323:        uint8 gcr;
        !           324: 
        !           325:        Event event { this };
1.1.1.2   root      326: 
1.1.1.8   root      327:        Monitor monitor { this };
                    328: 
1.1.1.2   root      329:        static const char * const errnames[];
1.1       root      330: };
1.1.1.2   root      331: 
1.1.1.10  root      332: extern DMACDevice *gDMAC;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.