diff --git a/src/emu/machine/atapihle.c b/src/emu/machine/atapihle.c index ecc6d69e789..2b21252e8fe 100644 --- a/src/emu/machine/atapihle.c +++ b/src/emu/machine/atapihle.c @@ -34,29 +34,15 @@ void atapi_hle_device::process_buffer() if (m_buffer_size > ATAPI_BUFFER_LENGTH || m_buffer_size == 0) 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) { case SCSI_PHASE_DATAOUT: - if (m_buffer_size > m_data_size) - { - 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); + wait_buffer(); break; case SCSI_PHASE_DATAIN: @@ -82,25 +68,7 @@ void atapi_hle_device::process_buffer() m_scsidev_device->WriteData( m_buffer, m_buffer_size ); m_data_size -= m_buffer_size; - if (m_buffer_size > m_data_size) - { - 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); + wait_buffer(); break; } } @@ -111,10 +79,14 @@ void atapi_hle_device::fill_buffer() switch (m_command) { case IDE_COMMAND_PACKET: - if (m_buffer_size > m_data_size) + 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; @@ -126,13 +98,21 @@ void atapi_hle_device::fill_buffer() m_status |= IDE_STATUS_DRQ; m_sector_count = ATAPI_INTERRUPT_REASON_IO; + + 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); } - - set_irq(ASSERT_LINE); break; 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() { // TODO: IDENTIFY DEVICE & READ SECTORS writes signature too. diff --git a/src/emu/machine/atapihle.h b/src/emu/machine/atapihle.h index b15802b1c56..f5a685edfaa 100644 --- a/src/emu/machine/atapihle.h +++ b/src/emu/machine/atapihle.h @@ -22,7 +22,13 @@ class atapi_hle_device : public ata_hle_device 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); - 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_IO = 0x02, // 1 = to host, 0 = to device @@ -59,6 +65,8 @@ protected: packet_command_response_t packet_command_response(); private: + void wait_buffer(); + int m_packet; int m_data_size; required_device m_scsidev_device; diff --git a/src/mess/machine/dccons.c b/src/mess/machine/dccons.c index 106c8ec846e..22f25d05bde 100644 --- a/src/mess/machine/dccons.c +++ b/src/mess/machine/dccons.c @@ -46,7 +46,7 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end ) //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 ) { @@ -55,7 +55,7 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end ) // get a sector from the SCSI device 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)+1 ] = d >> 8; } @@ -76,6 +76,8 @@ TIMER_CALLBACK_MEMBER(dc_cons_state::atapi_xfer_end ) atapi_xferbase += 2048; } + m_ata->write_dmack(0); + g1bus_regs[SB_GDST]=0; dc_sysctrl_regs[SB_ISTNRM] |= IST_DMA_GDROM; dc_update_interrupt_status();