diff --git a/src/emu/machine/ataflash.c b/src/emu/machine/ataflash.c index 7d748d0ee5b..ee473dfbfa0 100644 --- a/src/emu/machine/ataflash.c +++ b/src/emu/machine/ataflash.c @@ -1,5 +1,9 @@ #include "ataflash.h" +#define IDE_COMMAND_TAITO_GNET_UNLOCK_1 0xfe +#define IDE_COMMAND_TAITO_GNET_UNLOCK_2 0xfc +#define IDE_COMMAND_TAITO_GNET_UNLOCK_3 0x0f + const device_type ATA_FLASH_PCCARD = &device_creator; ata_flash_pccard_device::ata_flash_pccard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : @@ -7,13 +11,21 @@ ata_flash_pccard_device::ata_flash_pccard_device(const machine_config &mconfig, { } +void ata_flash_pccard_device::device_start() +{ + ide_hdd_device::device_start(); + + save_item(NAME(m_locked)); + save_item(NAME(m_gnetreadlock)); +} + void ata_flash_pccard_device::device_reset() { + ide_hdd_device::device_reset(); + m_locked = 0x1ff; m_gnetreadlock = 1; - ide_hdd_device::device_reset(); - UINT32 metalength; memset(m_cis, 0xff, 512); @@ -66,7 +78,7 @@ READ16_MEMBER( ata_flash_pccard_device::read_reg ) return 0x002e; case 0x201: - return m_locked ? 0x0001 : 0; + return m_gnetreadlock; default: return 0; @@ -99,3 +111,89 @@ WRITE16_MEMBER( ata_flash_pccard_device::write_reg ) } } } + +bool ata_flash_pccard_device::is_ready() +{ + return !m_gnetreadlock; +} + +bool ata_flash_pccard_device::process_command() +{ + UINT8 key[5]; + + switch (m_command) + { + case IDE_COMMAND_TAITO_GNET_UNLOCK_1: + //LOGPRINT(("IDE GNET Unlock 1\n")); + + m_sector_count = 1; + m_status |= IDE_STATUS_DRDY; + + set_irq(ASSERT_LINE); + return true; + + case IDE_COMMAND_TAITO_GNET_UNLOCK_2: + //LOGPRINT(("IDE GNET Unlock 2\n")); + + /* mark the buffer ready */ + m_status |= IDE_STATUS_DRQ; + + set_irq(ASSERT_LINE); + return true; + + case IDE_COMMAND_TAITO_GNET_UNLOCK_3: + //LOGPRINT(("IDE GNET Unlock 3\n")); + + /* key check */ + read_key(key); + if (m_feature == key[0] && m_sector_count == key[1] && m_sector_number == key[2] && m_cylinder_low == key[3] && m_cylinder_high == key[4]) + { + m_gnetreadlock = 0; + } + else + { + m_status &= ~IDE_STATUS_DRDY; + } + + set_irq(ASSERT_LINE); + return true; + + default: + if (m_gnetreadlock) + { + m_status |= IDE_STATUS_ERR; + m_error = IDE_ERROR_NONE; + m_status &= ~IDE_STATUS_DRDY; + return true; + } + + return ide_hdd_device::process_command(); + } +} + +void ata_flash_pccard_device::process_buffer() +{ + if (m_command == IDE_COMMAND_TAITO_GNET_UNLOCK_2) + { + UINT8 key[5] = { 0 }; + int i, bad = 0; + read_key(key); + + for (i=0; !bad && i<512; i++) + bad = ((i < 2 || i >= 7) && m_buffer[i]) || ((i >= 2 && i < 7) && m_buffer[i] != key[i-2]); + + if (bad) + { + m_status |= IDE_STATUS_ERR; + m_error = IDE_ERROR_NONE; + } + else + { + m_gnetreadlock= 0; + } + } + else + { + ide_hdd_device::process_buffer(); + } +} diff --git a/src/emu/machine/ataflash.h b/src/emu/machine/ataflash.h index 842e0624de7..b471d88d8bf 100644 --- a/src/emu/machine/ataflash.h +++ b/src/emu/machine/ataflash.h @@ -21,10 +21,16 @@ public: protected: // device-level overrides + virtual void device_start(); virtual void device_reset(); + virtual bool process_command(); + virtual void process_buffer(); + virtual bool is_ready(); + private: unsigned char m_cis[512]; + UINT8 m_gnetreadlock; int m_locked; }; diff --git a/src/emu/machine/idectrl.c b/src/emu/machine/idectrl.c index db35dea6821..80d19baf03f 100644 --- a/src/emu/machine/idectrl.c +++ b/src/emu/machine/idectrl.c @@ -351,7 +351,7 @@ void ide_controller_device::device_start() } dev->write_csel(i); - dev->write_dasp(m_slot[1]->dev() != NULL && m_slot[1]->dev()->device_present()); + dev->write_dasp(m_slot[1]->dev() != NULL); } } diff --git a/src/emu/machine/idehd.c b/src/emu/machine/idehd.c index ac2a3f319ee..f8c6fbbad52 100644 --- a/src/emu/machine/idehd.c +++ b/src/emu/machine/idehd.c @@ -56,9 +56,6 @@ #define IDE_COMMAND_SEEK 0x70 #define IDE_COMMAND_IDLE_IMMEDIATE 0xe1 #define IDE_COMMAND_IDLE 0xe3 -#define IDE_COMMAND_TAITO_GNET_UNLOCK_1 0xfe -#define IDE_COMMAND_TAITO_GNET_UNLOCK_2 0xfc -#define IDE_COMMAND_TAITO_GNET_UNLOCK_3 0x0f enum { @@ -98,6 +95,14 @@ ide_mass_storage_device::ide_mass_storage_device(const machine_config &mconfig, { } +void ide_mass_storage_device::update_irq() +{ + if (device_selected() && (m_device_control & 2) == 0) + m_irq_handler(m_irq); + else + m_irq_handler(CLEAR_LINE); +} + void ide_mass_storage_device::set_irq(int state) { if (m_irq != state) @@ -109,8 +114,7 @@ void ide_mass_storage_device::set_irq(int state) else LOG(("IDE interrupt clear\n")); - /* signal an interrupt */ - m_irq_handler(state); + update_irq(); } } @@ -148,12 +152,12 @@ WRITE_LINE_MEMBER( ide_mass_storage_device::write_dmack ) UINT32 ide_mass_storage_device::lba_address() { /* LBA direct? */ - if (m_cur_head_reg & 0x40) - return m_cur_sector + m_cur_cylinder * 256 + m_cur_head * 16777216; + if (m_device_head & 0x40) + return ((m_device_head & 0xf) << 24) | (m_cylinder_high << 16) | (m_cylinder_low << 8) | m_sector_number; /* standard CHS */ else - return (m_cur_cylinder * m_num_heads + m_cur_head) * m_num_sectors + m_cur_sector - 1; + return (((((m_cylinder_high << 8 ) | m_cylinder_low) * m_num_heads) + (m_device_head & 0xf)) * m_num_sectors) + m_sector_number - 1; } @@ -341,39 +345,29 @@ void ide_mass_storage_device::device_start() m_irq_handler.resolve_safe(); m_dmarq_handler.resolve_safe(); - save_item(NAME(m_features)); - - save_item(NAME(m_cur_cylinder)); - save_item(NAME(m_cur_sector)); - save_item(NAME(m_cur_head)); - save_item(NAME(m_cur_head_reg)); - - save_item(NAME(m_cur_lba)); - save_item(NAME(m_buffer)); save_item(NAME(m_buffer_offset)); - - save_item(NAME(m_status)); - save_item(NAME(m_command)); save_item(NAME(m_error)); - - save_item(NAME(m_device_control)); save_item(NAME(m_feature)); save_item(NAME(m_sector_count)); + save_item(NAME(m_sector_number)); + save_item(NAME(m_cylinder_low)); + save_item(NAME(m_cylinder_high)); + save_item(NAME(m_device_head)); + save_item(NAME(m_status)); + save_item(NAME(m_command)); + save_item(NAME(m_device_control)); + save_item(NAME(m_has_features)); + save_item(NAME(m_features)); + save_item(NAME(m_cur_lba)); save_item(NAME(m_irq)); save_item(NAME(m_dmarq)); save_item(NAME(m_sectors_until_int)); - save_item(NAME(m_master_password_enable)); save_item(NAME(m_user_password_enable)); - - save_item(NAME(m_gnetreadlock)); save_item(NAME(m_block_count)); - save_item(NAME(m_dma_active)); - save_item(NAME(m_verify_only)); - /* create a timer for timing status */ m_last_status_timer = timer_alloc(TID_NULL); m_reset_timer = timer_alloc(TID_RESET_CALLBACK); @@ -382,17 +376,15 @@ void ide_mass_storage_device::device_start() void ide_mass_storage_device::device_reset() { m_buffer_offset = 0; - m_gnetreadlock = 0; m_master_password_enable = (m_master_password != NULL); m_user_password_enable = (m_user_password != NULL); - m_error = IDE_ERROR_DIAGNOSTIC_PASSED; m_status = IDE_STATUS_DSC; - if (!m_gnetreadlock) + if (is_ready()) + { m_status |= IDE_STATUS_DRDY; - - m_cur_drive = 0; + } /* reset the drive state */ set_irq(CLEAR_LINE); @@ -405,6 +397,7 @@ void ide_mass_storage_device::device_timer(emu_timer &timer, device_timer_id id, { case TID_DELAYED_INTERRUPT: m_status &= ~IDE_STATUS_BSY; + set_irq(ASSERT_LINE); break; @@ -451,14 +444,18 @@ void ide_mass_storage_device::signal_delayed_interrupt(attotime time, int buffer void ide_mass_storage_device::next_sector() { /* LBA direct? */ - if (m_cur_head_reg & 0x40) + if (m_device_head & 0x40) { - m_cur_sector++; - if (m_cur_sector == 0) + m_sector_number++; + if (m_sector_number == 0) { - m_cur_cylinder++; - if (m_cur_cylinder == 0) - m_cur_head++; + m_cylinder_low++; + if (m_cylinder_low == 0) + { + m_cylinder_high++; + if( m_cylinder_high == 0) + m_device_head = (m_device_head & ~0xf) | ((m_device_head + 1) & 0xf); + } } } @@ -466,16 +463,18 @@ void ide_mass_storage_device::next_sector() else { /* sectors are 1-based */ - m_cur_sector++; - if (m_cur_sector > m_num_sectors) + m_sector_number++; + if (m_sector_number > m_num_sectors) { /* heads are 0 based */ - m_cur_sector = 1; - m_cur_head++; - if (m_cur_head >= m_num_heads) + m_sector_number = 1; + m_device_head = (m_device_head & ~0xf) | ((m_device_head + 1) & 0xf); + if ((m_device_head & 0xf) >= m_num_heads) { - m_cur_head = 0; - m_cur_cylinder++; + m_device_head &= ~0xf; + m_cylinder_low++; + if (m_cylinder_low == 0) + m_cylinder_high++; } } } @@ -537,12 +536,6 @@ void ide_mass_storage_device::read_sector_done() m_status &= ~IDE_STATUS_BSY; - /* GNET readlock check */ - if (m_gnetreadlock) - { - return; - } - /* now do the read */ count = read_sector(lba, m_buffer); @@ -555,16 +548,15 @@ void ide_mass_storage_device::read_sector_done() next_sector(); /* signal an interrupt */ - if (!m_verify_only) - m_sectors_until_int--; - if (m_sectors_until_int == 0 || m_sector_count == 1) + if (--m_sectors_until_int == 0 || m_sector_count == 1) { m_sectors_until_int = ((m_command == IDE_COMMAND_READ_MULTIPLE) ? m_block_count : 1); set_irq(ASSERT_LINE); } /* if we're just verifying we can read the next sector */ - if (m_verify_only) + if (m_command == IDE_COMMAND_VERIFY_SECTORS || + m_command == IDE_COMMAND_VERIFY_SECTORS_NORETRY ) { read_buffer_empty(); } @@ -572,7 +564,7 @@ void ide_mass_storage_device::read_sector_done() { m_status |= IDE_STATUS_DRQ; - if (m_dma_active) + if (m_command == IDE_COMMAND_READ_DMA) set_dmarq(ASSERT_LINE); } } @@ -675,6 +667,11 @@ void ide_mass_storage_device::write_buffer_full() m_status &= ~IDE_STATUS_DRQ; set_dmarq(CLEAR_LINE); + process_buffer(); +} + +void ide_mass_storage_device::process_buffer() +{ if (m_command == IDE_COMMAND_SECURITY_UNLOCK) { if (m_user_password_enable && memcmp(m_buffer, m_user_password, 2 + 32) == 0) @@ -705,25 +702,6 @@ void ide_mass_storage_device::write_buffer_full() if (m_master_password_enable || m_user_password_enable) security_error(); } - else if (m_command == IDE_COMMAND_TAITO_GNET_UNLOCK_2) - { - UINT8 key[5] = { 0 }; - int i, bad = 0; - read_key(key); - - for (i=0; !bad && i<512; i++) - bad = ((i < 2 || i >= 7) && m_buffer[i]) || ((i >= 2 && i < 7) && m_buffer[i] != key[i-2]); - - if (bad) - { - m_status |= IDE_STATUS_ERR; - m_error = IDE_ERROR_NONE; - } - else - { - m_gnetreadlock= 0; - } - } else { continue_write(); @@ -763,10 +741,8 @@ void ide_mass_storage_device::write_sector_done() { m_status |= IDE_STATUS_DRQ; - if (m_dma_active) - { + if (m_command == IDE_COMMAND_WRITE_DMA) set_dmarq(ASSERT_LINE); - } } } @@ -783,145 +759,111 @@ void ide_mass_storage_device::write_sector_done() } - /************************************* * * Handle IDE commands * *************************************/ -void ide_mass_storage_device::handle_command() +bool ide_mass_storage_device::process_command() { - UINT8 key[5]; - - /* implicitly clear interrupts & dmarq here */ - set_irq(CLEAR_LINE); - set_dmarq(CLEAR_LINE); - - m_status &= ~IDE_STATUS_ERR; - switch (m_command) { - case IDE_COMMAND_READ_SECTORS: - case IDE_COMMAND_READ_SECTORS_NORETRY: - LOGPRINT(("IDE Read multiple: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_READ_SECTORS: + case IDE_COMMAND_READ_SECTORS_NORETRY: + LOGPRINT(("IDE Read multiple: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 1; - m_dma_active = 0; - m_verify_only = 0; + m_sectors_until_int = 1; - /* start the read going */ - read_first_sector(); - break; + /* start the read going */ + read_first_sector(); + return true; - case IDE_COMMAND_READ_MULTIPLE: - LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_READ_MULTIPLE: + LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 1; - m_dma_active = 0; - m_verify_only = 0; + m_sectors_until_int = 1; - /* start the read going */ - read_first_sector(); - break; + /* start the read going */ + read_first_sector(); + return true; - case IDE_COMMAND_VERIFY_SECTORS: - case IDE_COMMAND_VERIFY_SECTORS_NORETRY: - LOGPRINT(("IDE Read verify multiple with/without retries: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_VERIFY_SECTORS: + case IDE_COMMAND_VERIFY_SECTORS_NORETRY: + LOGPRINT(("IDE Read verify multiple with/without retries: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 1; - m_dma_active = 0; - m_verify_only = 1; + /* reset the buffer */ + m_sectors_until_int = m_sector_count; - /* start the read going */ - read_first_sector(); - break; + /* start the read going */ + read_first_sector(); + return true; - case IDE_COMMAND_READ_DMA: - LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_READ_DMA: + LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = m_sector_count; - m_dma_active = 1; - m_verify_only = 0; + /* reset the buffer */ + m_sectors_until_int = m_sector_count; - /* start the read going */ - read_first_sector(); - break; + /* start the read going */ + read_first_sector(); + return true; - case IDE_COMMAND_WRITE_SECTORS: - case IDE_COMMAND_WRITE_SECTORS_NORETRY: - LOGPRINT(("IDE Write multiple: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_WRITE_SECTORS: + case IDE_COMMAND_WRITE_SECTORS_NORETRY: + LOGPRINT(("IDE Write multiple: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 1; - m_dma_active = 0; + /* reset the buffer */ + m_sectors_until_int = 1; - /* mark the buffer ready */ - m_status |= IDE_STATUS_DRQ; - break; + /* mark the buffer ready */ + m_status |= IDE_STATUS_DRQ; + return true; - case IDE_COMMAND_WRITE_MULTIPLE: - LOGPRINT(("IDE Write multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_WRITE_MULTIPLE: + LOGPRINT(("IDE Write multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 1; - m_dma_active = 0; + /* reset the buffer */ + m_sectors_until_int = 1; - /* mark the buffer ready */ - m_status |= IDE_STATUS_DRQ; - break; + /* mark the buffer ready */ + m_status |= IDE_STATUS_DRQ; + return true; - case IDE_COMMAND_WRITE_DMA: - LOGPRINT(("IDE Write multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", - m_cur_cylinder, m_cur_head, m_cur_sector, lba_address(), m_sector_count)); + case IDE_COMMAND_WRITE_DMA: + LOGPRINT(("IDE Write multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", + (m_cylinder_high << 8) | m_cylinder_low, m_device_head & 0xf, m_sector_number, lba_address(), m_sector_count)); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = m_sector_count; - m_dma_active = 1; + /* reset the buffer */ + m_sectors_until_int = m_sector_count; - /* mark the buffer ready */ - m_status |= IDE_STATUS_DRQ; + /* mark the buffer ready */ + m_status |= IDE_STATUS_DRQ; - /* start the read going */ - set_dmarq(ASSERT_LINE); - break; + /* start the read going */ + set_dmarq(ASSERT_LINE); + return true; - case IDE_COMMAND_SECURITY_UNLOCK: - LOGPRINT(("IDE Security Unlock\n")); + case IDE_COMMAND_SECURITY_UNLOCK: + LOGPRINT(("IDE Security Unlock\n")); - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 0; - m_dma_active = 0; + /* mark the buffer ready */ + m_status |= IDE_STATUS_DRQ; - /* mark the buffer ready */ - m_status |= IDE_STATUS_DRQ; + set_irq(ASSERT_LINE); + return true; - set_irq(ASSERT_LINE); - break; + case IDE_COMMAND_GET_INFO: + LOGPRINT(("IDE Read features\n")); - case IDE_COMMAND_GET_INFO: - LOGPRINT(("IDE Read features\n")); - - /* reset the buffer */ - m_buffer_offset = 0; + if (m_has_features) + { m_sector_count = 1; /* build the features page */ @@ -929,124 +871,86 @@ void ide_mass_storage_device::handle_command() /* indicate everything is ready */ m_status |= IDE_STATUS_DRQ; - m_status &= ~IDE_STATUS_BSY; /* signal an interrupt */ signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 1); - break; - - case IDE_COMMAND_DIAGNOSTIC: - m_error = IDE_ERROR_DIAGNOSTIC_PASSED; - - /* signal an interrupt */ - signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); - break; - - case IDE_COMMAND_RECALIBRATE: - /* signal an interrupt */ - signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); - break; - - case IDE_COMMAND_IDLE: - /* for timeout disabled value is 0 */ - m_sector_count = 0; - /* signal an interrupt */ - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_SET_CONFIG: - LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", m_cur_head + 1, m_sector_count)); - set_geometry(m_sector_count,m_cur_head + 1); - - /* signal an interrupt */ - signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); - break; - - case IDE_COMMAND_UNKNOWN_F9: - /* only used by Killer Instinct AFAICT */ - LOGPRINT(("IDE unknown command (F9)\n")); - - /* signal an interrupt */ - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_SET_FEATURES: - LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", m_feature, m_sector_count & 0xff, m_cur_sector, m_cur_cylinder & 0xff, m_cur_cylinder >> 8)); - - /* signal an interrupt */ - signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); - break; - - case IDE_COMMAND_SET_BLOCK_COUNT: - LOGPRINT(("IDE Set block count (%02X)\n", m_sector_count)); - - m_block_count = m_sector_count; - - /* signal an interrupt */ - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_TAITO_GNET_UNLOCK_1: - LOGPRINT(("IDE GNET Unlock 1\n")); - - m_sector_count = 1; - m_status |= IDE_STATUS_DRDY; - - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_TAITO_GNET_UNLOCK_2: - LOGPRINT(("IDE GNET Unlock 2\n")); - - /* reset the buffer */ - m_buffer_offset = 0; - m_sectors_until_int = 0; - m_dma_active = 0; - - /* mark the buffer ready */ - m_status |= IDE_STATUS_DRQ; - - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_TAITO_GNET_UNLOCK_3: - LOGPRINT(("IDE GNET Unlock 3\n")); - - /* key check */ - read_key(key); - if ((m_feature == key[0]) && (m_sector_count == key[1]) && (m_cur_sector == key[2]) && (m_cur_cylinder == (((UINT16)key[4]<<8)|key[3]))) - { - m_gnetreadlock= 0; - } - else - { - m_status &= ~IDE_STATUS_DRDY; - } - - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_SEEK: - /* - cur_cylinder, cur_sector and cur_head - are all already set in this case so no need - so that implements actual seek - */ - - /* for timeout disabled value is 0 */ - m_sector_count = 0; - /* signal an interrupt */ - set_irq(ASSERT_LINE); - break; - - - default: - LOGPRINT(("IDE unknown command (%02X)\n", m_command)); + } + else + { m_status |= IDE_STATUS_ERR; - m_error = IDE_ERROR_UNKNOWN_COMMAND; + m_error = IDE_ERROR_NONE; + m_status &= ~IDE_STATUS_DRDY; set_irq(ASSERT_LINE); - //debugger_break(device->machine()); - break; + } + return true; + + case IDE_COMMAND_DIAGNOSTIC: + m_error = IDE_ERROR_DIAGNOSTIC_PASSED; + + /* signal an interrupt */ + signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); + return true; + + case IDE_COMMAND_RECALIBRATE: + /* signal an interrupt */ + signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); + return true; + + case IDE_COMMAND_IDLE: + /* for timeout disabled value is 0 */ + m_sector_count = 0; + /* signal an interrupt */ + set_irq(ASSERT_LINE); + return true; + + case IDE_COMMAND_SET_CONFIG: + LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", (m_device_head & 0xf) + 1, m_sector_count)); + set_geometry(m_sector_count,(m_device_head & 0xf) + 1); + + /* signal an interrupt */ + signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); + return true; + + case IDE_COMMAND_UNKNOWN_F9: + /* only used by Killer Instinct AFAICT */ + LOGPRINT(("IDE unknown command (F9)\n")); + + /* signal an interrupt */ + set_irq(ASSERT_LINE); + return true; + + case IDE_COMMAND_SET_FEATURES: + LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", m_feature, m_sector_count & 0xff, m_sector_number, m_cylinder_low, m_cylinder_high)); + + /* signal an interrupt */ + signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); + return true; + + case IDE_COMMAND_SET_BLOCK_COUNT: + LOGPRINT(("IDE Set block count (%02X)\n", m_sector_count)); + + m_block_count = m_sector_count; + + /* signal an interrupt */ + set_irq(ASSERT_LINE); + return true; + + case IDE_COMMAND_SEEK: + /* + cur_cylinder, cur_sector and cur_head + are all already set in this case so no need + so that implements actual seek + */ + + /* for timeout disabled value is 0 */ + m_sector_count = 0; + + /* signal an interrupt */ + set_irq(ASSERT_LINE); + return true; + + default: + return false; } } @@ -1169,22 +1073,22 @@ READ16_MEMBER( ide_mass_storage_device::read_cs0 ) /* return the current sector */ case IDE_CS0_SECTOR_NUMBER_RW: - result = m_cur_sector; + result = m_sector_number; break; /* return the current cylinder LSB */ case IDE_CS0_CYLINDER_LOW_RW: - result = m_cur_cylinder & 0xff; + result = m_cylinder_low; break; /* return the current cylinder MSB */ case IDE_CS0_CYLINDER_HIGH_RW: - result = m_cur_cylinder >> 8; + result = m_cylinder_high; break; /* return the current head */ case IDE_CS0_DEVICE_HEAD_RW: - result = m_cur_head_reg; + result = m_device_head; break; /* return the current status and clear any pending interrupts */ @@ -1199,7 +1103,7 @@ READ16_MEMBER( ide_mass_storage_device::read_cs0 ) m_last_status_timer->adjust(attotime::never); } - if (!(m_status & IDE_STATUS_DRDY) && !m_gnetreadlock) + if (!(m_status & IDE_STATUS_DRDY) && is_ready()) { m_status |= IDE_STATUS_DRDY; } @@ -1210,7 +1114,6 @@ READ16_MEMBER( ide_mass_storage_device::read_cs0 ) { result = 0; } - break; /* log anything else */ @@ -1309,9 +1212,6 @@ void ide_mass_storage_device::write_dma( UINT16 data ) WRITE16_MEMBER( ide_mass_storage_device::write_cs0 ) { - if (!device_present()) - return; - /* logit */ if (offset != IDE_CS0_DATA_RW) LOG(("%s:IDE cs0 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); @@ -1369,25 +1269,24 @@ WRITE16_MEMBER( ide_mass_storage_device::write_cs0 ) /* current sector */ case IDE_CS0_SECTOR_NUMBER_RW: - m_cur_sector = data; + m_sector_number = data; break; /* current cylinder LSB */ case IDE_CS0_CYLINDER_LOW_RW: - m_cur_cylinder = (m_cur_cylinder & 0xff00) | (data & 0xff); + m_cylinder_low = data; break; /* current cylinder MSB */ case IDE_CS0_CYLINDER_HIGH_RW: - m_cur_cylinder = ((data << 8) & 0xff00) | (m_cur_cylinder & 0xff); + m_cylinder_high = data; break; /* current head */ case IDE_CS0_DEVICE_HEAD_RW: - // LBA mode = data & 0x40 - m_cur_drive = (data & 0x10) >> 4; - m_cur_head = data & 0x0f; - m_cur_head_reg = data; + m_device_head = data; + + update_irq(); break; /* command */ @@ -1395,7 +1294,25 @@ WRITE16_MEMBER( ide_mass_storage_device::write_cs0 ) m_command = data; if (device_selected() || m_command == IDE_COMMAND_DIAGNOSTIC) - handle_command(); + { + /* implicitly clear interrupts & dmarq here */ + set_irq(CLEAR_LINE); + set_dmarq(CLEAR_LINE); + + m_buffer_offset = 0; + m_sectors_until_int = 0; + + m_status &= ~IDE_STATUS_ERR; + + if (!process_command()) + { + LOGPRINT(("IDE unknown command (%02X)\n", m_command)); + m_status |= IDE_STATUS_ERR; + m_error = IDE_ERROR_UNKNOWN_COMMAND; + set_irq(ASSERT_LINE); + //debugger_break(device->machine()); + } + } break; } } @@ -1403,9 +1320,6 @@ WRITE16_MEMBER( ide_mass_storage_device::write_cs0 ) WRITE16_MEMBER( ide_mass_storage_device::write_cs1 ) { - if (!device_present()) - return; - /* logit */ LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); @@ -1421,11 +1335,7 @@ WRITE16_MEMBER( ide_mass_storage_device::write_cs1 ) case IDE_CS1_DEVICE_CONTROL_W: m_device_control = data; - if (data & 0x02) - { - // nIEN - logerror( "%s: write_cs1 %04x %04x %04x nIEN not supported\n", machine().describe_context(), offset, data, mem_mask ); - } + update_irq(); if (data & 0x04) { @@ -1495,6 +1405,8 @@ void ide_hdd_device::device_reset() UINT32 metalength; if (m_handle->read_metadata (HARD_DISK_IDENT_METADATA_TAG, 0, m_features, IDE_DISK_SECTOR_SIZE, metalength) != CHDERR_NONE) ide_build_features(); + + m_has_features = 1; } } diff --git a/src/emu/machine/idehd.h b/src/emu/machine/idehd.h index 3cce4f41daa..4e6b9e90016 100644 --- a/src/emu/machine/idehd.h +++ b/src/emu/machine/idehd.h @@ -57,7 +57,7 @@ public: virtual DECLARE_WRITE_LINE_MEMBER(write_csel) = 0; virtual DECLARE_WRITE_LINE_MEMBER(write_dasp) = 0; - virtual bool device_present() = 0; + virtual bool is_ready() { return true; } virtual UINT8 *get_features() = 0; UINT8 m_master_password_enable; @@ -98,15 +98,30 @@ protected: virtual int write_sector(UINT32 lba, const void *buffer) = 0; virtual void read_key(UINT8 key[]) = 0; - bool device_selected() { return m_csel == m_cur_drive && device_present(); } - bool single_device() { return m_csel == 0 && m_dasp == 0 && device_present(); } + bool device_selected() { return m_csel == (m_device_head & 0x10) >> 4; } + bool single_device() { return m_csel == 0 && m_dasp == 0; } void set_irq(int state); void set_dmarq(int state); void ide_build_features(); - UINT8 m_gnetreadlock; + virtual bool process_command(); + virtual void process_buffer(); + UINT8 m_buffer[IDE_DISK_SECTOR_SIZE]; + UINT16 m_buffer_offset; + UINT8 m_error; + UINT8 m_feature; + UINT16 m_sector_count; + UINT8 m_sector_number; + UINT8 m_cylinder_low; + UINT8 m_cylinder_high; + UINT8 m_device_head; + UINT8 m_status; + UINT8 m_command; + UINT8 m_device_control; + + int m_has_features; UINT8 m_features[IDE_DISK_SECTOR_SIZE]; UINT16 m_num_cylinders; UINT8 m_num_sectors; @@ -124,9 +139,9 @@ private: void security_error(); void continue_read(); void read_first_sector(); - void handle_command(); void read_buffer_empty(); void write_buffer_full(); + void update_irq(); int m_csel; int m_dasp; @@ -134,30 +149,10 @@ private: int m_dmarq; int m_irq; - int m_cur_drive; - UINT16 m_cur_cylinder; - UINT8 m_cur_sector; - UINT8 m_cur_head; - UINT8 m_cur_head_reg; UINT32 m_cur_lba; - - UINT8 m_status; - UINT8 m_error; - UINT8 m_command; - - UINT8 m_buffer[IDE_DISK_SECTOR_SIZE]; - UINT16 m_buffer_offset; - - UINT8 m_device_control; - UINT8 m_feature; - UINT16 m_sector_count; UINT16 m_block_count; - UINT16 m_sectors_until_int; - UINT8 m_dma_active; - UINT8 m_verify_only; - emu_timer * m_last_status_timer; emu_timer * m_reset_timer; }; @@ -181,7 +176,6 @@ protected: // optional information overrides virtual machine_config_constructor device_mconfig_additions() const; - virtual bool device_present() { return (m_disk != NULL); } virtual void read_key(UINT8 key[]); chd_file *m_handle; diff --git a/src/mame/drivers/chihiro.c b/src/mame/drivers/chihiro.c index 49d5398ee00..2feb2652859 100644 --- a/src/mame/drivers/chihiro.c +++ b/src/mame/drivers/chihiro.c @@ -2664,7 +2664,6 @@ public: virtual int read_sector(UINT32 lba, void *buffer); virtual int write_sector(UINT32 lba, const void *buffer); - virtual bool device_present() { return true; } virtual void read_key(UINT8 key[]) { } protected: // device-level overrides