|
|
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.8 root 14: #include "monitor.h"
1.1.1.10! root 15: #include "event.h"
1.1.1.9 root 16: #include <array>
1.1 root 17:
18: struct DMAC
19: {
1.1.1.2 root 20: static const uint32 CSR = 0x00; // .B
21: static const uint32 CER = 0x01; // .B
22: static const uint32 DCR = 0x04; // .B
23: static const uint32 OCR = 0x05; // .B
24: static const uint32 SCR = 0x06; // .B
25: static const uint32 CCR = 0x07; // .B
26: static const uint32 MTC = 0x0a; // .W
27: static const uint32 MAR = 0x0c; // .L
28: static const uint32 DAR = 0x14; // .L
29: static const uint32 BTC = 0x1a; // .W
30: static const uint32 BAR = 0x1c; // .L
31: static const uint32 NIV = 0x25; // .B
32: static const uint32 EIV = 0x27; // .B
33: static const uint32 MFC = 0x29; // .B
34: static const uint32 CPR = 0x2d; // .B
35: static const uint32 DFC = 0x31; // .B
36: static const uint32 BFC = 0x39; // .B
37: static const uint32 GCR = 0x3f; // .B (ch#3のみ)
38:
39: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
40: // CSR | COC | BTC | NDT | ERR | ACT | --- | PCT | PCS |
41: //
42: static const uint32 CSR_COC = 0x80; // Channel Operation Complete
43: static const uint32 CSR_BTC = 0x40; // Block Transfer Complete
44: static const uint32 CSR_NDT = 0x20; // Normal Device Termination
45: static const uint32 CSR_ERR = 0x10; // Error Bit
46: static const uint32 CSR_ACT = 0x08; // Channel Active
47: static const uint32 CSR_PCT = 0x02; // PCL Transition
48: static const uint32 CSR_PCS = 0x01; // PCL Input Line State
49:
50: // CER
51: static const uint32 CER_NO_ERROR = 0x00; // No Error
52: static const uint32 CER_CONFIG = 0x01; // Configuration Error
53: static const uint32 CER_OPER_TIMING = 0x02; // Operation Timing Error
54: static const uint32 CER_ADDR_MAR = 0x05; // Address error in MAR
55: static const uint32 CER_ADDR_DAR = 0x06; // Address error in DAR
56: static const uint32 CER_ADDR_BAR = 0x07; // Address error in BAR
57: static const uint32 CER_BUS_MAR = 0x09; // Bus error in MAR
58: static const uint32 CER_BUS_DAR = 0x0a; // Bus error in DAR
59: static const uint32 CER_BUS_BAR = 0x0b; // Bus error in BAR
60: static const uint32 CER_COUNT_MTC = 0x0d; // Count error in MTC
61: static const uint32 CER_COUNT_BTC = 0x0f; // Count error in BTC
62: static const uint32 CER_EXT_ABORT = 0x10; // External Abort
63: static const uint32 CER_SOFT_ABORT = 0x11; // Software Abort
64:
65: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
66: // DCR | XRM | DTYP | DPS | --- | PCL |
67: static const uint32 DCR_XRM_BURST = 0; // Burst Transfer
68: static const uint32 DCR_XRM_CYCLE_WO_HOLD = 2; // Cycle Steal without Hold
69: static const uint32 DCR_XRM_CYCLE_WITH_HOLD = 3;// Cycle Steal with Hold
70: static const uint32 DCR_DTYP_68000 = 0; // 68000 devices
71: static const uint32 DCR_DTYP_6800 = 1; // 6800 devices
72: static const uint32 DCR_DTYP_ACK = 2; // Devices with ACK
73: static const uint32 DCR_DTYP_ACK_REDY = 3; // Devices with ACK+READY
74: static const uint32 DCR_DPS_8BIT = 0; // 8bit port
75: static const uint32 DCR_DPS_16BIT = 1; // 16bit port
76: static const uint32 DCR_PCL_STATUS = 0; // Status Input
77: static const uint32 DCR_PCL_STATUS_INTR = 1; // Status Input with Interrupt
78: static const uint32 DCR_PCL_PULSE = 2; // Start Pulse
79: static const uint32 DCR_PCL_ABORT = 3; // Abort Input
80:
81: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
82: // OCR | DIR | --- | SIZE | CHAIN | REQG |
83: //
84: static const uint32 OCR_DIR_MtoD = 0; // Memory to Device
85: static const uint32 OCR_DIR_DtoM = 1; // Device to Memory
86: static const uint32 OCR_SIZE_8BIT = 0; // 8bit
87: static const uint32 OCR_SIZE_16BIT = 1; // 16bit
88: static const uint32 OCR_SIZE_32BIT = 2; // 32bit
89: static const uint32 OCR_SIZE_8BIT_UP = 3; // 8bit (Non-Pack Operation)
90: static const uint32 OCR_CHAIN_NOCHAIN = 0; // Chain operation is disabled
91: static const uint32 OCR_CHAIN_ARRAY = 2; // Array Chaining
92: static const uint32 OCR_CHAIN_LINK = 3; // Linked Array Chaining
93: static const uint32 OCR_REQG_AUTO_LIM = 0; // Auto Request (Limited)
94: static const uint32 OCR_REQG_AUTO_MAX = 1; // AUto Request (Max)
95: static const uint32 OCR_REQG_EXTERNAL = 2; // External Request
96: static const uint32 OCR_REQG_AUTOFIRST = 3; // Auto first then ext.
97:
98: // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
99: // SCR | --- --- --- --- | MAC | DAC |
100: static const uint32 SCR_NO_COUNT = 0; // Does not count
101: static const uint32 SCR_COUNT_UP = 1; // Count up
102: static const uint32 SCR_COUNT_DOWN = 2; // Count down
103:
104: // CCR
105: static const uint32 CCR_STR = 0x80; // Start Operation
106: static const uint32 CCR_CNT = 0x40; // Continue Operation
107: static const uint32 CCR_HLT = 0x20; // Halt Operation
108: static const uint32 CCR_SAB = 0x10; // Software Abort
109: static const uint32 CCR_INT = 0x08; // Interrupt Enable
1.1 root 110:
111: // 各チャンネル
1.1.1.2 root 112: struct Channel {
113: // 二次変数など
114: int ch; // チャンネル番号
115: const char *desc; // チャンネルの用途(モニタ表示用)
116: DMACDevice *parent;
1.1.1.10! root 117: uint8 priority; // 現在の実効プライオリティ
1.1.1.2 root 118:
119: // レジスタ
120:
121: // CSR
122: uint8 csr; // COC,BTC,NDT,ERR を保持
123: bool active; // ACT
124: bool pcl; // PCL の状態 (High が true)
125: bool prev_pcl; // 前回の PCL の状態 (High が true)
1.1.1.6 root 126: bool IsINTR() const { // CSR の割り込み要因が立っていれば true
127: // XXX PCT は未対応
128: return (csr & (CSR_COC | CSR_BTC | CSR_NDT | CSR_ERR));
129: }
1.1.1.2 root 130:
1.1 root 131: uint8 cer;
132: uint8 dcr;
1.1.1.2 root 133: uint32 GetXRM() const { return (dcr >> 6); }
134: uint32 GetDTYP() const { return (dcr >> 4) & 3; }
135: uint32 GetDPS() const { return (dcr >> 3) & 1; }
136: uint32 GetPCL() const { return (dcr & 3); }
137:
1.1 root 138: uint8 ocr;
1.1.1.2 root 139: uint32 GetDIR() const { return (ocr >> 7); }
140: uint32 GetSIZE() const { return (ocr >> 4) & 3; }
141: uint32 GetCHAIN() const { return (ocr >> 2) & 3; }
142: uint32 GetREQG() const { return (ocr & 3); }
143:
144: // 転送種別 (DPS と SIZE から決まる)
145: uint32 xfertype;
146:
1.1 root 147: uint8 scr;
1.1.1.2 root 148: uint32 GetMAC() const { return (scr >> 2) & 3; }
149: uint32 GetDAC() const { return (scr & 3); }
150:
1.1 root 151: uint8 ccr;
1.1.1.2 root 152:
1.1 root 153: uint16 mtc;
154: uint32 mar;
155: uint32 dar;
156: uint16 btc;
157: uint32 bar;
158: uint8 niv;
159: uint8 eiv;
160: uint8 mfc;
161: uint8 cpr;
162: uint8 dfc;
163: uint8 bfc;
1.1.1.2 root 164:
165: uint8 PeekCSR() const;
166: void WriteCSR(uint32 data);
167: void WriteCCR(uint32 data);
168:
169: // 転送開始
170: void StartTransfer();
1.1 root 171: } chan[4];
172:
173: // 全体
174: uint8 gcr;
175: };
176:
1.1.1.8 root 177: class DMACDevice : public IODevice
1.1 root 178: {
1.1.1.3 root 179: using inherited = IODevice;
1.1 root 180:
181: static const int baseaddr = 0xe84000;
182:
183: public:
184: DMACDevice();
1.1.1.6 root 185: virtual ~DMACDevice() override;
1.1 root 186:
1.1.1.10! root 187: void ResetHard(bool poweron) override;
1.1.1.2 root 188:
189: // 転送
1.1.1.10! root 190: void StartTransfer();
1.1.1.2 root 191: void AbortTransfer(DMAC::Channel *chan);
192:
1.1.1.6 root 193: // 割り込みアクノリッジ
194: int InterruptAcknowledge();
195:
1.1.1.3 root 196: protected:
197: // BusIO インタフェース
198: static const uint NPORT = 256;
1.1.1.7 root 199: uint64 Read(uint32 offset);
200: uint64 Write(uint32 offset, uint32 data);
201: uint64 Peek(uint32 offset);
1.1.1.3 root 202:
1.1 root 203: private:
1.1.1.8 root 204: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
1.1.1.10! root 205:
1.1.1.4 root 206: void MonitorReg4(TextScreen&,
207: int x, int y, uint32 reg, const char * const *names);
1.1 root 208:
1.1.1.6 root 209: // 割り込み信号線の状態を変更
210: void ChangeInterrupt();
211:
1.1.1.10! root 212: // 転送イベントコールバック
! 213: void StartCallback(Event& ev);
! 214: void ReadCallback(Event& ev);
! 215: void WriteCallback(Event& ev);
! 216: void DoneCallback(Event& ev);
! 217:
! 218: // 転送中エラー
! 219: void Error(uint64);
! 220:
1.1 root 221: struct DMAC dmac {};
1.1.1.10! root 222:
! 223: Event event { this };
! 224:
! 225: DMAC::Channel *xfer_chan {}; // 現在転送中のチャンネル
! 226: uint32 xfer_src; // 転送中ソースアドレス
! 227: uint32 xfer_dst; // 転送中ディスティネーションアドレス
! 228: uint32 xfer_data; // 転送中データ
! 229: int xfer_retry {}; // 転送リトライ
1.1.1.2 root 230:
1.1.1.8 root 231: Monitor monitor { this };
232:
1.1.1.2 root 233: static const char * const errnames[];
1.1 root 234: };
1.1.1.2 root 235:
1.1.1.10! root 236: extern DMACDevice *gDMAC;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.