Example #1
0
static void check_interrupts( running_machine &machine )
{
	/* if interrupts are disabled, bail */
	if ( (dmac_data.cntr & CNTR_INTEN) == 0 )
		return;

	/* if no interrupts are pending, bail */
	if ( (dmac_data.istr & ISTR_INT_P) == 0 )
		return;

	/* otherwise, generate the IRQ */
	amiga_custom_w(machine.device("maincpu")->memory().space(AS_PROGRAM), REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff);
}
Example #2
0
static TIMER_CALLBACK(tp6525_delayed_irq)
{
	amiga_state *state = machine.driver_data<amiga_state>();
	(void)param;

	if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
	{
		amiga_custom_w(machine.device("maincpu")->memory().space(AS_PROGRAM), REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff);
	}
	else
	{
		tp6525_delayed_timer->adjust(attotime::from_msec(1));
	}
}
Example #3
0
static void amigacd_tpi6525_irq_trampoline(device_t *device, int level)
{
	amiga_state *state = device->machine().driver_data<amiga_state>();
	LOG(( "TPI6525 Interrupt: level = %d\n", level ));

	if ( level )
	{
		if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
		{
			amiga_custom_w(device->machine().device("maincpu")->memory().space(AS_PROGRAM), REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff);
		}
		else
		{
			/* we *have to* deliver the irq, so if we can't, delay it and try again later */
			tp6525_delayed_timer->adjust(attotime::from_msec(1));
		}
	}
}
Example #4
0
void amiga_fdc::dma_done()
{
	dma_state = DMA_IDLE;
	address_space *space = machine().device("maincpu")->memory().space(AS_PROGRAM);
	amiga_custom_w(space, REG_INTREQ, 0x8000 | INTENA_DSKBLK, 0xffff);
}
Example #5
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;
		}
		}
	}
}