Fixed ct486 booting with two chd's loaded. Moved the GNET protection command processing to ataflash.c (nw)

This commit is contained in:
smf- 2013-06-15 17:34:48 +00:00
parent 782df63b1d
commit c1cf6dabff
6 changed files with 361 additions and 352 deletions

View File

@ -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::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();
}
}

View File

@ -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;
};

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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