void amiga_fdc::dma_check() { bool was_writing = dskbyt & 0x2000; dskbyt &= 0x9fff; if(dma_enabled()) { if(dma_state == IDLE) { dma_state = adkcon & 0x0400 ? DMA_WAIT_START : DMA_RUNNING_BYTE_0; if(dma_state == DMA_RUNNING_BYTE_0) { if(!(dsklen & 0x3fff)) dma_done(); else if(dsklen & 0x4000) { dskbyt |= 0x2000; cur_live.bit_counter = 0; dma_value = dma_read(); } } } else { dskbyt |= 0x4000; if(dsklen & 0x4000) dskbyt |= 0x2000; } } else dma_state = IDLE; if(was_writing && !(dskbyt & 0x2000)) cur_live.pll.stop_writing(floppy, cur_live.tm); if(!was_writing && (dskbyt & 0x2000)) cur_live.pll.start_writing(cur_live.tm); }
void amiga_fdc::dma_check() { if(dma_enabled()) { if(dma_state == IDLE) { dma_state = adkcon & 0x0400 ? DMA_WAIT_START : DMA_RUNNING_BYTE_0; if(dma_state == DMA_RUNNING_BYTE_0 && !(dsklen & 0x3fff)) dma_done(); } } else dma_state = IDLE; }
void amiga_fdc::dma_write(UINT16 value) { amiga_state *state = machine().driver_data<amiga_state>(); (*state->m_chip_ram_w)(state, dskpt, value); dskpt += 2; dsklen--; if(dsklen & 0x3fff) dma_state = DMA_RUNNING_BYTE_0; else dma_done(); }
void amiga_fdc::dma_write(uint16_t value) { amiga_state *state = machine().driver_data<amiga_state>(); state->chip_ram_w(dskpt, value); dskpt += 2; dsklen--; if(dsklen & 0x3fff) dma_state = DMA_RUNNING_BYTE_0; else dma_done(); }
UINT16 amiga_fdc::dma_read() { amiga_state *state = machine().driver_data<amiga_state>(); UINT16 res = state->chip_ram_r(dskpt); dskpt += 2; dsklen--; // This loses the last word. So does the real hardware. if(dsklen & 0x3fff) dma_state = DMA_RUNNING_BYTE_0; else dma_done(); return res; }
/* * Stop ethernet board */ void eth_stop() { register long l; /* stop chip and disable DMA access */ out_word(LA_RAP, RDP_CSR0); out_word(LA_CSR, CSR_STOP); for (l = 0; (in_word(LA_CSR) & CSR_STOP) == 0; l++) { if (l >= MAXLOOP) { printf("Lance failed to stop\n"); break; } } dma_done(NE_DMACHANNEL); }
static void dwmmc_intr(void *arg) { struct mmc_command *cmd; struct dwmmc_softc *sc; uint32_t reg; sc = arg; DWMMC_LOCK(sc); cmd = sc->curcmd; /* First handle SDMMC controller interrupts */ reg = READ4(sc, SDMMC_MINTSTS); if (reg) { dprintf("%s 0x%08x\n", __func__, reg); if (reg & DWMMC_CMD_ERR_FLAGS) { WRITE4(sc, SDMMC_RINTSTS, DWMMC_CMD_ERR_FLAGS); dprintf("cmd err 0x%08x cmd 0x%08x\n", reg, cmd->opcode); cmd->error = MMC_ERR_TIMEOUT; } if (reg & DWMMC_DATA_ERR_FLAGS) { WRITE4(sc, SDMMC_RINTSTS, DWMMC_DATA_ERR_FLAGS); dprintf("data err 0x%08x cmd 0x%08x\n", reg, cmd->opcode); cmd->error = MMC_ERR_FAILED; if (!sc->use_pio) { dma_done(sc, cmd); dma_stop(sc); } } if (reg & SDMMC_INTMASK_CMD_DONE) { dwmmc_cmd_done(sc); sc->cmd_done = 1; WRITE4(sc, SDMMC_RINTSTS, SDMMC_INTMASK_CMD_DONE); } if (reg & SDMMC_INTMASK_ACD) { sc->acd_rcvd = 1; WRITE4(sc, SDMMC_RINTSTS, SDMMC_INTMASK_ACD); } if (reg & SDMMC_INTMASK_DTO) { sc->dto_rcvd = 1; WRITE4(sc, SDMMC_RINTSTS, SDMMC_INTMASK_DTO); } if (reg & SDMMC_INTMASK_CD) { /* XXX: Handle card detect */ WRITE4(sc, SDMMC_RINTSTS, SDMMC_INTMASK_CD); } } if (sc->use_pio) { if (reg & (SDMMC_INTMASK_RXDR|SDMMC_INTMASK_DTO)) { pio_read(sc, cmd); } if (reg & (SDMMC_INTMASK_TXDR|SDMMC_INTMASK_DTO)) { pio_write(sc, cmd); } } else { /* Now handle DMA interrupts */ reg = READ4(sc, SDMMC_IDSTS); if (reg) { dprintf("dma intr 0x%08x\n", reg); if (reg & (SDMMC_IDINTEN_TI | SDMMC_IDINTEN_RI)) { WRITE4(sc, SDMMC_IDSTS, (SDMMC_IDINTEN_TI | SDMMC_IDINTEN_RI)); WRITE4(sc, SDMMC_IDSTS, SDMMC_IDINTEN_NI); dma_done(sc, cmd); } } } dwmmc_tasklet(sc); DWMMC_UNLOCK(sc); }
void amiga_fdc::live_run(const attotime &limit) { amiga_state *state = machine().driver_data<amiga_state>(); if(cur_live.state == IDLE || cur_live.next_state != -1) return; for(;;) { switch(cur_live.state) { case RUNNING: { if(!(dskbyt & 0x2000)) { int bit = cur_live.pll.get_next_bit(cur_live.tm, floppy, limit); if(bit < 0) return; cur_live.shift_reg = (cur_live.shift_reg << 1) | bit; cur_live.bit_counter++; if((adkcon & 0x0200) && !(cur_live.shift_reg & 0x80)) { cur_live.bit_counter--; // Avoid any risk of livelock live_delay(RUNNING_SYNCPOINT); return; } if(cur_live.bit_counter > 8) fatalerror("amiga_fdc::live_run - cur_live.bit_counter > 8\n"); if(cur_live.bit_counter == 8) { live_delay(RUNNING_SYNCPOINT); return; } if(dskbyt & 0x1000) { if(cur_live.shift_reg != dsksync) { live_delay(RUNNING_SYNCPOINT); return; } } else { if(cur_live.shift_reg == dsksync) { live_delay(RUNNING_SYNCPOINT); return; } } } else { int bit = (dma_state == DMA_RUNNING_BYTE_0 ? 15 : 7) - cur_live.bit_counter; if(cur_live.pll.write_next_bit((dma_value >> bit) & 1, cur_live.tm, floppy, limit)) return; cur_live.bit_counter++; if(cur_live.bit_counter > 8) fatalerror("amiga_fdc::live_run - cur_live.bit_counter > 8\n"); if(cur_live.bit_counter == 8) { live_delay(RUNNING_SYNCPOINT); return; } } break; } case RUNNING_SYNCPOINT: { if(!(dskbyt & 0x2000)) { if(cur_live.shift_reg == dsksync) { if(adkcon & 0x0400) { if(dma_state == DMA_WAIT_START) { cur_live.bit_counter = 0; if(!(dsklen & 0x3fff)) dma_done(); else if(dsklen & 0x4000) { dskbyt |= 0x2000; cur_live.bit_counter = 0; dma_value = dma_read(); } else dma_write(dsksync); } else if(dma_state != DMA_IDLE) { dma_write(dsksync); cur_live.bit_counter = 0; } else if(cur_live.bit_counter != 8) cur_live.bit_counter = 0; } dskbyt |= 0x1000; state->custom_chip_w(REG_INTREQ, INTENA_SETCLR | INTENA_DSKSYN); } else dskbyt &= ~0x1000; if(cur_live.bit_counter == 8) { dskbyt = (dskbyt & 0xff00) | 0x8000 | (cur_live.shift_reg & 0xff); cur_live.bit_counter = 0; switch(dma_state) { case DMA_IDLE: case DMA_WAIT_START: break; case DMA_RUNNING_BYTE_0: dma_value = (cur_live.shift_reg & 0xff) << 8; dma_state = DMA_RUNNING_BYTE_1; break; case DMA_RUNNING_BYTE_1: { dma_value |= cur_live.shift_reg & 0xff; dma_write(dma_value); break; } } } } else { if(cur_live.bit_counter != 8) fatalerror("amiga_fdc::live_run - cur_live.bit_counter != 8\n"); cur_live.bit_counter = 0; switch(dma_state) { case DMA_IDLE: case DMA_WAIT_START: break; case DMA_RUNNING_BYTE_0: dma_state = DMA_RUNNING_BYTE_1; break; case DMA_RUNNING_BYTE_1: { dma_value = dma_read(); break; } } } cur_live.state = RUNNING; checkpoint(); break; } } } }
void amiga_fdc::live_run(attotime limit) { if(cur_live.state == IDLE || cur_live.next_state != -1) return; for(;;) { switch(cur_live.state) { case RUNNING: { int bit = cur_live.pll.get_next_bit(cur_live.tm, floppy, limit); if(bit < 0) return; cur_live.shift_reg = (cur_live.shift_reg << 1) | bit; cur_live.bit_counter++; if((adkcon & 0x0200) && !(cur_live.shift_reg & 0x80)) { cur_live.bit_counter--; // Avoid any risk of livelock live_delay(RUNNING_SYNCPOINT); return; } if(cur_live.bit_counter > 8) fatalerror("amiga_fdc::live_run - cur_live.bit_counter > 8"); if(cur_live.bit_counter == 8) { live_delay(RUNNING_SYNCPOINT); return; } if(dskbyt & 0x1000) { if(cur_live.shift_reg != dsksync) { live_delay(RUNNING_SYNCPOINT); return; } } else { if(cur_live.shift_reg == dsksync) { live_delay(RUNNING_SYNCPOINT); return; } } break; } case RUNNING_SYNCPOINT: { if(cur_live.shift_reg == dsksync) { if(adkcon & 0x0400) { if(dma_state == DMA_WAIT_START) { cur_live.bit_counter = 0; if(!(dsklen & 0x3fff)) dma_done(); else dma_write(dsksync); } else if(dma_state != DMA_IDLE) { dma_write(dsksync); cur_live.bit_counter = 0; } else if(cur_live.bit_counter != 8) cur_live.bit_counter = 0; } dskbyt |= 0x1000; address_space *space = machine().device("maincpu")->memory().space(AS_PROGRAM); amiga_custom_w(space, REG_INTREQ, 0x8000 | INTENA_DSKSYN, 0xffff); } else dskbyt &= ~0x1000; if(cur_live.bit_counter == 8) { dskbyt = (dskbyt & 0xff00) | 0x8000 | (cur_live.shift_reg & 0xff); cur_live.bit_counter = 0; switch(dma_state) { case DMA_IDLE: case DMA_WAIT_START: break; case DMA_RUNNING_BYTE_0: dma_value = (cur_live.shift_reg & 0xff) << 8; dma_state = DMA_RUNNING_BYTE_1; break; case DMA_RUNNING_BYTE_1: { dma_value |= cur_live.shift_reg & 0xff; dma_write(dma_value); break; } } } cur_live.state = RUNNING; checkpoint(); break; } } } }
int scsiicmd(char target, char lun, u_char *cbuf, int clen, char *addr, int len) { volatile caddr_t sr; int i; DPRINTF(("scsiicmd: [%x, %d] -> %d (%lx, %d)\n",*cbuf, clen, target, (long)addr, len)); sr = P_SCSI; if (sc->sc_state != SCSI_IDLE) { scsierror("scsiiscmd: bad state"); return EIO; } sc->sc_result = 0; /* select target */ sr[ESP_CMD] = ESPCMD_FLUSH; DELAY(10); sr[ESP_SELID] = target; sr[ESP_FIFO] = MSG_IDENTIFY(lun, 0); for (i=0; i<clen; i++) sr[ESP_FIFO] = cbuf[i]; sr[ESP_CMD] = ESPCMD_SELATN; sc->sc_state = SCSI_SELECTING; while(sc->sc_state != SCSI_DONE) { if (scsi_wait_for_intr()) /* maybe we'd better use real intrs ? */ return EIO; if (sc->sc_state == SCSI_DMA) { /* registers are not valid on dma intr */ sc->sc_status = sc->sc_seqstep = sc->sc_intrstatus = 0; DPRINTF(("scsiicmd: dma intr\n")); } else { /* scsi processing */ sc->sc_status = sr[ESP_STAT]; sc->sc_seqstep = sr[ESP_STEP]; sc->sc_intrstatus = sr[ESP_INTR]; DPRINTF(("scsiicmd: regs[intr=%x, stat=%x, step=%x]\n", sc->sc_intrstatus, sc->sc_status, sc->sc_seqstep)); } if (sc->sc_intrstatus & ESPINTR_SBR) { scsierror("scsi bus reset"); return EIO; } if ((sc->sc_status & ESPSTAT_GE) || (sc->sc_intrstatus & ESPINTR_ILL)) { scsierror("software error"); return EIO; } if (sc->sc_status & ESPSTAT_PE) { scsierror("parity error"); return EIO; } switch(sc->sc_state) { case SCSI_SELECTING: if (sc->sc_intrstatus & ESPINTR_DIS) { sc->sc_state = SCSI_IDLE; return EUNIT; /* device not present */ } #define ESPINTR_DONE (ESPINTR_BS | ESPINTR_FC) if ((sc->sc_intrstatus & ESPINTR_DONE) != ESPINTR_DONE) { scsierror("selection failed"); return EIO; } sc->sc_state = SCSI_HASBUS; break; case SCSI_HASBUS: if (sc->sc_intrstatus & ESPINTR_DIS) { scsierror("target disconnected"); return EIO; } break; case SCSI_DMA: if (sc->sc_intrstatus & ESPINTR_DIS) { scsierror("target disconnected"); return EIO; } if (dma_done() != 0) return EIO; continue; case SCSI_CLEANUP: if (sc->sc_intrstatus & ESPINTR_DIS) { sc->sc_state = SCSI_DONE; continue; } DPRINTF(("hmm ... no disconnect on cleanup?\n")); sc->sc_state = SCSI_DONE; /* maybe ... */ break; } /* transfer information now */ switch(sc->sc_status & ESPSTAT_PHASE) { case DATA_IN_PHASE: if (dma_start(addr, len) != 0) return EIO; break; case DATA_OUT_PHASE: scsierror("data out phase not implemented"); return EIO; case STATUS_PHASE: DPRINTF(("status phase: ")); sr[ESP_CMD] = ESPCMD_ICCS; sc->sc_result = scsi_getbyte(sr); DPRINTF(("status is 0x%x.\n", sc->sc_result)); break; case MSG_IN_PHASE: if (scsi_msgin() != 0) return EIO; break; default: DPRINTF(("phase not implemented: 0x%x.\n", sc->sc_status & ESPSTAT_PHASE)); scsierror("bad phase"); return EIO; } } sc->sc_state = SCSI_IDLE; return -sc->sc_result; }