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