mirror of
https://github.com/holub/mame
synced 2025-05-07 23:02:33 +03:00
Preliminary ATAPI/Dreamcast DMA. The timing needs to be moved into the devices, so the timing hack can be removed from the driver. [smf]
This commit is contained in:
parent
712b2a838c
commit
7b00ef3c97
@ -34,29 +34,15 @@ void atapi_hle_device::process_buffer()
|
|||||||
if (m_buffer_size > ATAPI_BUFFER_LENGTH || m_buffer_size == 0)
|
if (m_buffer_size > ATAPI_BUFFER_LENGTH || m_buffer_size == 0)
|
||||||
m_buffer_size = ATAPI_BUFFER_LENGTH;
|
m_buffer_size = ATAPI_BUFFER_LENGTH;
|
||||||
|
|
||||||
// TODO: dma flag
|
if (m_feature & ATAPI_FEATURES_FLAG_OVL)
|
||||||
|
{
|
||||||
|
printf( "ATAPI_FEATURES_FLAG_OVL not supported\n" );
|
||||||
|
}
|
||||||
|
|
||||||
switch (phase)
|
switch (phase)
|
||||||
{
|
{
|
||||||
case SCSI_PHASE_DATAOUT:
|
case SCSI_PHASE_DATAOUT:
|
||||||
if (m_buffer_size > m_data_size)
|
wait_buffer();
|
||||||
{
|
|
||||||
m_buffer_size = m_data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_cylinder_low = m_buffer_size & 0xff;
|
|
||||||
m_cylinder_high = m_buffer_size >> 8;
|
|
||||||
|
|
||||||
if (m_buffer_size > 0)
|
|
||||||
{
|
|
||||||
m_status |= IDE_STATUS_DRQ;
|
|
||||||
m_sector_count = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_irq(ASSERT_LINE);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_PHASE_DATAIN:
|
case SCSI_PHASE_DATAIN:
|
||||||
@ -82,25 +68,7 @@ void atapi_hle_device::process_buffer()
|
|||||||
m_scsidev_device->WriteData( m_buffer, m_buffer_size );
|
m_scsidev_device->WriteData( m_buffer, m_buffer_size );
|
||||||
m_data_size -= m_buffer_size;
|
m_data_size -= m_buffer_size;
|
||||||
|
|
||||||
if (m_buffer_size > m_data_size)
|
wait_buffer();
|
||||||
{
|
|
||||||
m_buffer_size = m_data_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_cylinder_low = m_buffer_size & 0xff;
|
|
||||||
m_cylinder_high = m_buffer_size >> 8;
|
|
||||||
|
|
||||||
if (m_buffer_size > 0)
|
|
||||||
{
|
|
||||||
m_status |= IDE_STATUS_DRQ;
|
|
||||||
m_sector_count = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_irq(ASSERT_LINE);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,10 +79,14 @@ void atapi_hle_device::fill_buffer()
|
|||||||
switch (m_command)
|
switch (m_command)
|
||||||
{
|
{
|
||||||
case IDE_COMMAND_PACKET:
|
case IDE_COMMAND_PACKET:
|
||||||
if (m_buffer_size > m_data_size)
|
if (m_buffer_size >= m_data_size)
|
||||||
{
|
{
|
||||||
m_buffer_size = m_data_size;
|
m_buffer_size = m_data_size;
|
||||||
}
|
}
|
||||||
|
else if (m_buffer_size & 1)
|
||||||
|
{
|
||||||
|
m_buffer_size--;
|
||||||
|
}
|
||||||
|
|
||||||
m_cylinder_low = m_buffer_size & 0xff;
|
m_cylinder_low = m_buffer_size & 0xff;
|
||||||
m_cylinder_high = m_buffer_size >> 8;
|
m_cylinder_high = m_buffer_size >> 8;
|
||||||
@ -126,13 +98,21 @@ void atapi_hle_device::fill_buffer()
|
|||||||
|
|
||||||
m_status |= IDE_STATUS_DRQ;
|
m_status |= IDE_STATUS_DRQ;
|
||||||
m_sector_count = ATAPI_INTERRUPT_REASON_IO;
|
m_sector_count = ATAPI_INTERRUPT_REASON_IO;
|
||||||
|
|
||||||
|
if (m_feature & ATAPI_FEATURES_FLAG_DMA)
|
||||||
|
{
|
||||||
|
set_dmarq(ASSERT_LINE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_irq(ASSERT_LINE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD;
|
m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD;
|
||||||
}
|
|
||||||
|
|
||||||
set_irq(ASSERT_LINE);
|
set_irq(ASSERT_LINE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDE_COMMAND_IDENTIFY_PACKET_DEVICE:
|
case IDE_COMMAND_IDENTIFY_PACKET_DEVICE:
|
||||||
@ -145,6 +125,41 @@ void atapi_hle_device::fill_buffer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void atapi_hle_device::wait_buffer()
|
||||||
|
{
|
||||||
|
if (m_buffer_size >= m_data_size)
|
||||||
|
{
|
||||||
|
m_buffer_size = m_data_size;
|
||||||
|
}
|
||||||
|
else if (m_buffer_size & 1)
|
||||||
|
{
|
||||||
|
m_buffer_size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_cylinder_low = m_buffer_size & 0xff;
|
||||||
|
m_cylinder_high = m_buffer_size >> 8;
|
||||||
|
|
||||||
|
if (m_buffer_size > 0)
|
||||||
|
{
|
||||||
|
m_status |= IDE_STATUS_DRQ;
|
||||||
|
m_sector_count = 0;
|
||||||
|
|
||||||
|
if (m_feature & ATAPI_FEATURES_FLAG_DMA)
|
||||||
|
{
|
||||||
|
set_dmarq(ASSERT_LINE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_irq(ASSERT_LINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD;
|
||||||
|
set_irq(ASSERT_LINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void atapi_hle_device::signature()
|
void atapi_hle_device::signature()
|
||||||
{
|
{
|
||||||
// TODO: IDENTIFY DEVICE & READ SECTORS writes signature too.
|
// TODO: IDENTIFY DEVICE & READ SECTORS writes signature too.
|
||||||
|
@ -22,7 +22,13 @@ class atapi_hle_device : public ata_hle_device
|
|||||||
public:
|
public:
|
||||||
atapi_hle_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source);
|
atapi_hle_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source);
|
||||||
|
|
||||||
enum
|
enum atapi_features_flag_t
|
||||||
|
{
|
||||||
|
ATAPI_FEATURES_FLAG_DMA = 0x01,
|
||||||
|
ATAPI_FEATURES_FLAG_OVL = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
enum atapi_interrupt_reason_t
|
||||||
{
|
{
|
||||||
ATAPI_INTERRUPT_REASON_CD = 0x01, // 1 = command, 0 = data
|
ATAPI_INTERRUPT_REASON_CD = 0x01, // 1 = command, 0 = data
|
||||||
ATAPI_INTERRUPT_REASON_IO = 0x02, // 1 = to host, 0 = to device
|
ATAPI_INTERRUPT_REASON_IO = 0x02, // 1 = to host, 0 = to device
|
||||||
@ -59,6 +65,8 @@ protected:
|
|||||||
packet_command_response_t packet_command_response();
|
packet_command_response_t packet_command_response();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void wait_buffer();
|
||||||
|
|
||||||
int m_packet;
|
int m_packet;
|
||||||
int m_data_size;
|
int m_data_size;
|
||||||
required_device<scsihle_device> m_scsidev_device;
|
required_device<scsihle_device> m_scsidev_device;
|
||||||
|
@ -46,7 +46,7 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end )
|
|||||||
|
|
||||||
//mame_printf_debug("ATAPI: xfer_end. xferlen = %d\n", atapi_xferlen);
|
//mame_printf_debug("ATAPI: xfer_end. xferlen = %d\n", atapi_xferlen);
|
||||||
|
|
||||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
m_ata->write_dmack(1);
|
||||||
|
|
||||||
while (atapi_xferlen > 0 )
|
while (atapi_xferlen > 0 )
|
||||||
{
|
{
|
||||||
@ -55,7 +55,7 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end )
|
|||||||
// get a sector from the SCSI device
|
// get a sector from the SCSI device
|
||||||
for (int i = 0; i < 2048/2; i++)
|
for (int i = 0; i < 2048/2; i++)
|
||||||
{
|
{
|
||||||
int d = m_ata->read_cs0(space, 0, 0xffff);
|
int d = m_ata->read_dma();
|
||||||
sector_buffer[ i*2 ] = d & 0xff;
|
sector_buffer[ i*2 ] = d & 0xff;
|
||||||
sector_buffer[ (i*2)+1 ] = d >> 8;
|
sector_buffer[ (i*2)+1 ] = d >> 8;
|
||||||
}
|
}
|
||||||
@ -76,6 +76,8 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end )
|
|||||||
atapi_xferbase += 2048;
|
atapi_xferbase += 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_ata->write_dmack(0);
|
||||||
|
|
||||||
g1bus_regs[SB_GDST]=0;
|
g1bus_regs[SB_GDST]=0;
|
||||||
dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_GDROM;
|
dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_GDROM;
|
||||||
dc_update_interrupt_status();
|
dc_update_interrupt_status();
|
||||||
|
Loading…
Reference in New Issue
Block a user