| 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); |