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

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

unix.superglobalmegacorp.com

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