29 |
#ifdef DEBUG_ESP |
#ifdef DEBUG_ESP |
30 |
#define DPRINTF(fmt, args...) \ |
#define DPRINTF(fmt, args...) \ |
31 |
do { printf("ESP: " fmt , ##args); } while (0) |
do { printf("ESP: " fmt , ##args); } while (0) |
32 |
|
#define pic_set_irq(irq, level) \ |
33 |
|
do { printf("ESP: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0) |
34 |
#else |
#else |
35 |
#define DPRINTF(fmt, args...) |
#define DPRINTF(fmt, args...) |
36 |
#endif |
#endif |
40 |
#define ESP_MAXREG 0x3f |
#define ESP_MAXREG 0x3f |
41 |
#define TI_BUFSZ 65536 |
#define TI_BUFSZ 65536 |
42 |
#define DMA_VER 0xa0000000 |
#define DMA_VER 0xa0000000 |
43 |
|
#define DMA_INTR 1 |
44 |
|
#define DMA_INTREN 0x10 |
45 |
#define DMA_LOADED 0x04000000 |
#define DMA_LOADED 0x04000000 |
46 |
|
|
47 |
typedef struct ESPState { |
typedef struct ESPState { |
70 |
#define INTR_FC 0x08 |
#define INTR_FC 0x08 |
71 |
#define INTR_BS 0x10 |
#define INTR_BS 0x10 |
72 |
#define INTR_DC 0x20 |
#define INTR_DC 0x20 |
73 |
|
#define INTR_RST 0x80 |
74 |
|
|
75 |
#define SEQ_0 0x0 |
#define SEQ_0 0x0 |
76 |
#define SEQ_CD 0x4 |
#define SEQ_CD 0x4 |
103 |
s->ti_rptr = 0; |
s->ti_rptr = 0; |
104 |
s->ti_wptr = 0; |
s->ti_wptr = 0; |
105 |
|
|
106 |
if (target > 4 || !s->bd[target]) { // No such drive |
if (target >= 4 || !s->bd[target]) { // No such drive |
107 |
s->rregs[4] = STAT_IN; |
s->rregs[4] = STAT_IN; |
108 |
s->rregs[5] = INTR_DC; |
s->rregs[5] = INTR_DC; |
109 |
s->rregs[6] = SEQ_0; |
s->rregs[6] = SEQ_0; |
110 |
s->espdmaregs[0] |= 1; |
s->espdmaregs[0] |= DMA_INTR; |
111 |
pic_set_irq(s->irq, 1); |
pic_set_irq(s->irq, 1); |
112 |
return; |
return; |
113 |
} |
} |
197 |
s->rregs[4] = STAT_IN | STAT_TC | STAT_DI; |
s->rregs[4] = STAT_IN | STAT_TC | STAT_DI; |
198 |
s->rregs[5] = INTR_BS | INTR_FC; |
s->rregs[5] = INTR_BS | INTR_FC; |
199 |
s->rregs[6] = SEQ_CD; |
s->rregs[6] = SEQ_CD; |
200 |
s->espdmaregs[0] |= 1; |
s->espdmaregs[0] |= DMA_INTR; |
201 |
pic_set_irq(s->irq, 1); |
pic_set_irq(s->irq, 1); |
202 |
} |
} |
203 |
|
|
214 |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
215 |
s->rregs[5] = INTR_BS | INTR_FC; |
s->rregs[5] = INTR_BS | INTR_FC; |
216 |
s->rregs[6] = SEQ_CD; |
s->rregs[6] = SEQ_CD; |
|
s->espdmaregs[0] |= 1; |
|
217 |
} else { |
} else { |
218 |
memcpy(s->ti_buf, buf, len); |
memcpy(s->ti_buf, buf, len); |
219 |
s->ti_size = dmalen; |
s->ti_size = dmalen; |
220 |
s->ti_rptr = 0; |
s->ti_rptr = 0; |
221 |
s->ti_wptr = 0; |
s->ti_wptr = 0; |
222 |
|
s->rregs[7] = dmalen; |
223 |
} |
} |
224 |
|
s->espdmaregs[0] |= DMA_INTR; |
225 |
pic_set_irq(s->irq, 1); |
pic_set_irq(s->irq, 1); |
226 |
|
|
227 |
} |
} |
248 |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; |
249 |
s->rregs[5] = INTR_BS; |
s->rregs[5] = INTR_BS; |
250 |
s->rregs[6] = 0; |
s->rregs[6] = 0; |
251 |
s->espdmaregs[0] |= 1; |
s->espdmaregs[0] |= DMA_INTR; |
252 |
} else { |
} else { |
253 |
s->ti_size = dmalen; |
s->ti_size = dmalen; |
254 |
s->ti_rptr = 0; |
s->ti_rptr = 0; |
255 |
s->ti_wptr = 0; |
s->ti_wptr = 0; |
256 |
|
s->rregs[7] = dmalen; |
257 |
} |
} |
258 |
pic_set_irq(s->irq, 1); |
pic_set_irq(s->irq, 1); |
259 |
} |
} |
272 |
uint32_t saddr; |
uint32_t saddr; |
273 |
|
|
274 |
saddr = (addr & ESP_MAXREG) >> 2; |
saddr = (addr & ESP_MAXREG) >> 2; |
275 |
|
DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); |
276 |
switch (saddr) { |
switch (saddr) { |
277 |
case 2: |
case 2: |
278 |
// FIFO |
// FIFO |
286 |
s->ti_wptr = 0; |
s->ti_wptr = 0; |
287 |
} |
} |
288 |
break; |
break; |
289 |
|
case 5: |
290 |
|
// interrupt |
291 |
|
// Clear status bits except TC |
292 |
|
s->rregs[4] &= STAT_TC; |
293 |
|
pic_set_irq(s->irq, 0); |
294 |
|
s->espdmaregs[0] &= ~DMA_INTR; |
295 |
|
break; |
296 |
default: |
default: |
297 |
break; |
break; |
298 |
} |
} |
|
DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); |
|
|
|
|
299 |
return s->rregs[saddr]; |
return s->rregs[saddr]; |
300 |
} |
} |
301 |
|
|
330 |
break; |
break; |
331 |
case 1: |
case 1: |
332 |
DPRINTF("Flush FIFO (%2.2x)\n", val); |
DPRINTF("Flush FIFO (%2.2x)\n", val); |
333 |
s->rregs[6] = 0; |
//s->ti_size = 0; |
334 |
s->rregs[5] = INTR_FC; |
s->rregs[5] = INTR_FC; |
335 |
|
s->rregs[6] = 0; |
336 |
break; |
break; |
337 |
case 2: |
case 2: |
338 |
DPRINTF("Chip reset (%2.2x)\n", val); |
DPRINTF("Chip reset (%2.2x)\n", val); |
340 |
break; |
break; |
341 |
case 3: |
case 3: |
342 |
DPRINTF("Bus reset (%2.2x)\n", val); |
DPRINTF("Bus reset (%2.2x)\n", val); |
343 |
|
s->rregs[5] = INTR_RST; |
344 |
|
if (!(s->wregs[8] & 0x40)) { |
345 |
|
s->espdmaregs[0] |= DMA_INTR; |
346 |
|
pic_set_irq(s->irq, 1); |
347 |
|
} |
348 |
break; |
break; |
349 |
case 0x10: |
case 0x10: |
350 |
handle_ti(s); |
handle_ti(s); |
381 |
break; |
break; |
382 |
case 9 ... 10: |
case 9 ... 10: |
383 |
break; |
break; |
384 |
case 11 ... 15: |
case 11: |
385 |
|
s->rregs[saddr] = val & 0x15; |
386 |
|
break; |
387 |
|
case 12 ... 15: |
388 |
s->rregs[saddr] = val; |
s->rregs[saddr] = val; |
389 |
break; |
break; |
390 |
default: |
default: |
425 |
DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->espdmaregs[saddr], val); |
DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->espdmaregs[saddr], val); |
426 |
switch (saddr) { |
switch (saddr) { |
427 |
case 0: |
case 0: |
428 |
if (!(val & 0x10)) |
if (!(val & DMA_INTREN)) |
429 |
pic_set_irq(s->irq, 0); |
pic_set_irq(s->irq, 0); |
430 |
if (val & 0x80) { |
if (val & 0x80) { |
431 |
esp_reset(s); |
esp_reset(s); |