Fixed Z80 DMA ready signal handling. [Curt Coder]

This commit is contained in:
Curt Coder 2010-03-07 15:29:29 +00:00
parent ee2134845d
commit 3b241320a3

View File

@ -154,7 +154,8 @@ struct _z80dma_t
UINT16 addressB; UINT16 addressB;
UINT16 count; UINT16 count;
UINT8 rdy; int rdy;
int force_ready;
UINT8 reset_pointer; UINT8 reset_pointer;
UINT8 is_read; UINT8 is_read;
@ -227,6 +228,11 @@ static void trigger_interrupt(running_device *device, int level)
} }
} }
static int is_ready(z80dma_t *z80dma)
{
return (z80dma->force_ready) || (z80dma->rdy == READY_ACTIVE_HIGH(z80dma));
}
/*------------------------------------------------- /*-------------------------------------------------
z80dma_do_read - perform DMA read z80dma_do_read - perform DMA read
-------------------------------------------------*/ -------------------------------------------------*/
@ -379,7 +385,7 @@ static TIMER_CALLBACK( z80dma_timerproc )
z80dma->dma_enabled = 0; //FIXME: Correct? z80dma->dma_enabled = 0; //FIXME: Correct?
z80dma->status = 0x19; z80dma->status = 0x19;
if(!(z80dma->rdy ^ READY_ACTIVE_HIGH(z80dma))) z80dma->status |= 0x02; // ready line status z80dma->status |= !is_ready(z80dma) << 1; // ready line status
if(TRANSFER_MODE(z80dma) == TM_TRANSFER) z80dma->status |= 0x10; // no match found if(TRANSFER_MODE(z80dma) == TM_TRANSFER) z80dma->status |= 0x10; // no match found
@ -404,7 +410,7 @@ static void z80dma_update_status(running_device *device)
attotime next; attotime next;
/* no transfer is active right now; is there a transfer pending right now? */ /* no transfer is active right now; is there a transfer pending right now? */
pending_transfer = z80dma->rdy & z80dma->dma_enabled; pending_transfer = is_ready(z80dma) & z80dma->dma_enabled;
if (pending_transfer) if (pending_transfer)
{ {
@ -419,8 +425,11 @@ static void z80dma_update_status(running_device *device)
} }
else else
{ {
/* no transfers active right now */ if (z80dma->is_read)
timer_reset(z80dma->timer, attotime_never); {
/* no transfers active right now */
timer_reset(z80dma->timer, attotime_never);
}
} }
/* set the busreq line */ /* set the busreq line */
@ -503,7 +512,10 @@ WRITE8_DEVICE_HANDLER( z80dma_w )
} }
else if ((data & 0x83) == 0x83) // WR6 else if ((data & 0x83) == 0x83) // WR6
{ {
z80dma->dma_enabled = 0;
WR6(z80dma) = data; WR6(z80dma) = data;
switch (data) switch (data)
{ {
case COMMAND_ENABLE_AFTER_RETI: case COMMAND_ENABLE_AFTER_RETI:
@ -517,7 +529,7 @@ WRITE8_DEVICE_HANDLER( z80dma_w )
WR3(z80dma) &= ~0x20; WR3(z80dma) &= ~0x20;
z80dma->ip = 0; z80dma->ip = 0;
z80dma->ius = 0; z80dma->ius = 0;
z80dma->rdy = 0; z80dma->force_ready = 0;
z80dma->status |= 0x08; z80dma->status |= 0x08;
break; break;
case COMMAND_INITIATE_READ_SEQUENCE: case COMMAND_INITIATE_READ_SEQUENCE:
@ -534,7 +546,7 @@ WRITE8_DEVICE_HANDLER( z80dma_w )
case COMMAND_RESET: case COMMAND_RESET:
if (LOG) logerror("Reset\n"); if (LOG) logerror("Reset\n");
z80dma->dma_enabled = 0; z80dma->dma_enabled = 0;
z80dma->rdy = 1; z80dma->force_ready = 0;
/* Needs six reset commands to reset the DMA */ /* Needs six reset commands to reset the DMA */
{ {
UINT8 WRi; UINT8 WRi;
@ -557,14 +569,11 @@ WRITE8_DEVICE_HANDLER( z80dma_w )
case COMMAND_DISABLE_DMA: case COMMAND_DISABLE_DMA:
if (LOG) logerror("Disable DMA\n"); if (LOG) logerror("Disable DMA\n");
z80dma->dma_enabled = 0; z80dma->dma_enabled = 0;
z80dma->rdy = 1 ^ ((WR5(z80dma) & 0x8)>>3);
z80dma_rdy_w(device, z80dma->rdy);
break; break;
case COMMAND_ENABLE_DMA: case COMMAND_ENABLE_DMA:
if (LOG) logerror("Enable DMA\n"); if (LOG) logerror("Enable DMA\n");
z80dma->dma_enabled = 1; z80dma->dma_enabled = 1;
z80dma->rdy = (WR5(z80dma) & 0x8)>>3; z80dma_update_status(device);
z80dma_rdy_w(device, z80dma->rdy);
break; break;
case COMMAND_READ_MASK_FOLLOWS: case COMMAND_READ_MASK_FOLLOWS:
if (LOG) logerror("Set Read Mask\n"); if (LOG) logerror("Set Read Mask\n");
@ -587,8 +596,8 @@ WRITE8_DEVICE_HANDLER( z80dma_w )
break; break;
case COMMAND_FORCE_READY: case COMMAND_FORCE_READY:
if (LOG) logerror("Force ready\n"); if (LOG) logerror("Force ready\n");
z80dma->rdy = (WR5(z80dma) & 0x8)>>3; z80dma->force_ready = 1;
z80dma_rdy_w(device, z80dma->rdy); z80dma_update_status(device);
break; break;
case COMMAND_ENABLE_INTERRUPTS: case COMMAND_ENABLE_INTERRUPTS:
if (LOG) logerror("Enable IRQ\n"); if (LOG) logerror("Enable IRQ\n");
@ -640,16 +649,14 @@ WRITE8_DEVICE_HANDLER( z80dma_w )
static TIMER_CALLBACK( z80dma_rdy_write_callback ) static TIMER_CALLBACK( z80dma_rdy_write_callback )
{ {
running_device *device = (running_device *)ptr; running_device *device = (running_device *)ptr;
int state = param & 0x01;
z80dma_t *z80dma = get_safe_token(device); z80dma_t *z80dma = get_safe_token(device);
/* normalize state */ z80dma->rdy = param;
z80dma->rdy = 1 ^ state ^ READY_ACTIVE_HIGH(z80dma); z80dma->status = (z80dma->status & 0xFD) | (!is_ready(z80dma) << 1);
z80dma->status = (z80dma->status & 0xFD) | (z80dma->rdy<<1);
z80dma_update_status(device); z80dma_update_status(device);
if (z80dma->rdy && INT_ON_READY(z80dma)) if (is_ready(z80dma) && INT_ON_READY(z80dma))
{ {
trigger_interrupt(device, INT_RDY); trigger_interrupt(device, INT_RDY);
} }
@ -662,11 +669,10 @@ static TIMER_CALLBACK( z80dma_rdy_write_callback )
WRITE_LINE_DEVICE_HANDLER( z80dma_rdy_w ) WRITE_LINE_DEVICE_HANDLER( z80dma_rdy_w )
{ {
z80dma_t *z80dma = get_safe_token(device); z80dma_t *z80dma = get_safe_token(device);
int param;
param = (state ? 1 : 0);
if (LOG) logerror("RDY: %d Active High: %d\n", state, READY_ACTIVE_HIGH(z80dma)); if (LOG) logerror("RDY: %d Active High: %d\n", state, READY_ACTIVE_HIGH(z80dma));
timer_call_after_resynch(device->machine, (void *) device, param, z80dma_rdy_write_callback);
timer_call_after_resynch(device->machine, (void *) device, state, z80dma_rdy_write_callback);
} }
/*------------------------------------------------- /*-------------------------------------------------
@ -797,6 +803,7 @@ static DEVICE_START( z80dma )
state_save_register_device_item(device, 0, z80dma->addressB); state_save_register_device_item(device, 0, z80dma->addressB);
state_save_register_device_item(device, 0, z80dma->count); state_save_register_device_item(device, 0, z80dma->count);
state_save_register_device_item(device, 0, z80dma->rdy); state_save_register_device_item(device, 0, z80dma->rdy);
state_save_register_device_item(device, 0, z80dma->force_ready);
state_save_register_device_item(device, 0, z80dma->is_read); state_save_register_device_item(device, 0, z80dma->is_read);
state_save_register_device_item(device, 0, z80dma->cur_cycle); state_save_register_device_item(device, 0, z80dma->cur_cycle);
state_save_register_device_item(device, 0, z80dma->latch); state_save_register_device_item(device, 0, z80dma->latch);
@ -812,6 +819,7 @@ static DEVICE_RESET( z80dma )
z80dma->status = 0; z80dma->status = 0;
z80dma->rdy = 0; z80dma->rdy = 0;
z80dma->force_ready = 0;
z80dma->num_follow = 0; z80dma->num_follow = 0;
z80dma->dma_enabled = 0; z80dma->dma_enabled = 0;
z80dma->read_num_follow = z80dma->read_cur_follow = 0; z80dma->read_num_follow = z80dma->read_cur_follow = 0;