Пример #1
0
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);

}
Пример #2
0
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;
}
Пример #3
0
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();
}
Пример #4
0
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();
}
Пример #5
0
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;
}
Пример #6
0
/*
 * 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);
}
Пример #7
0
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);
}
Пример #8
0
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;
		}
		}
	}
}
Пример #9
0
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;
		}
		}
	}
}
Пример #10
0
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;
}