mirror of
https://github.com/holub/mame
synced 2025-05-23 22:20:01 +03:00
Fixed Z80 DMA ready signal handling. [Curt Coder]
This commit is contained in:
parent
ee2134845d
commit
3b241320a3
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user