Renamed some #defines to match up closer to the ATA specification. Added validation to register access, switching Primal Rage 2 away from using the DMA interface in it's DMA handler as the game only executes normal read commands (nw)

This commit is contained in:
smf- 2013-06-14 19:17:43 +00:00
parent 358509548a
commit e3bbb0a27d
5 changed files with 469 additions and 292 deletions

View File

@ -232,6 +232,15 @@ WRITE16_MEMBER( ide_controller_device::write_cs1 )
m_slot[i]->dev()->write_cs1(space, offset, data, mem_mask); m_slot[i]->dev()->write_cs1(space, offset, data, mem_mask);
} }
WRITE_LINE_MEMBER( ide_controller_device::write_dmack )
{
// printf( "write_dmack %04x\n", state );
for (int i = 0; i < 2; i++)
if (m_slot[i]->dev() != NULL)
m_slot[i]->dev()->write_dmack(state);
}
WRITE8_MEMBER( ide_controller_device::write_via_config ) WRITE8_MEMBER( ide_controller_device::write_via_config )
{ {
// printf( "write via config %04x %04x %04x\n", offset, data, mem_mask ); // printf( "write via config %04x %04x %04x\n", offset, data, mem_mask );
@ -416,7 +425,9 @@ bus_master_ide_controller_device::bus_master_ide_controller_device(const machine
dma_last_buffer(0), dma_last_buffer(0),
bus_master_command(0), bus_master_command(0),
bus_master_status(0), bus_master_status(0),
bus_master_descriptor(0) bus_master_descriptor(0),
m_irq(0),
m_dmarq(0)
{ {
} }
@ -568,6 +579,8 @@ WRITE32_MEMBER( bus_master_ide_controller_device::ide_bus_master32_w )
void bus_master_ide_controller_device::execute_dma() void bus_master_ide_controller_device::execute_dma()
{ {
write_dmack(ASSERT_LINE);
while (m_dmarq && (bus_master_status & IDE_BUSMASTER_STATUS_ACTIVE)) while (m_dmarq && (bus_master_status & IDE_BUSMASTER_STATUS_ACTIVE))
{ {
/* if we're out of space, grab the next descriptor */ /* if we're out of space, grab the next descriptor */
@ -624,4 +637,6 @@ void bus_master_ide_controller_device::execute_dma()
} }
} }
} }
write_dmack(CLEAR_LINE);
} }

View File

@ -94,9 +94,11 @@ public:
UINT16 read_dma(); UINT16 read_dma();
DECLARE_READ16_MEMBER(read_cs0); DECLARE_READ16_MEMBER(read_cs0);
DECLARE_READ16_MEMBER(read_cs1); DECLARE_READ16_MEMBER(read_cs1);
void write_dma(UINT16 data); void write_dma(UINT16 data);
DECLARE_WRITE16_MEMBER(write_cs0); DECLARE_WRITE16_MEMBER(write_cs0);
DECLARE_WRITE16_MEMBER(write_cs1); DECLARE_WRITE16_MEMBER(write_cs1);
DECLARE_WRITE_LINE_MEMBER(write_dmack);
DECLARE_READ8_MEMBER(read_via_config); DECLARE_READ8_MEMBER(read_via_config);
DECLARE_WRITE8_MEMBER(write_via_config); DECLARE_WRITE8_MEMBER(write_via_config);

View File

@ -21,16 +21,19 @@
#define TIME_SEEK_MULTISECTOR (attotime::from_msec(13)) #define TIME_SEEK_MULTISECTOR (attotime::from_msec(13))
#define TIME_NO_SEEK_MULTISECTOR (attotime::from_nsec(16300)) #define TIME_NO_SEEK_MULTISECTOR (attotime::from_nsec(16300))
#define IDE_BANK0_DATA 0 #define IDE_CS0_DATA_RW 0
#define IDE_BANK0_ERROR 1 #define IDE_CS0_ERROR_R 1
#define IDE_BANK0_SECTOR_COUNT 2 #define IDE_CS0_FEATURE_W 1
#define IDE_BANK0_SECTOR_NUMBER 3 #define IDE_CS0_SECTOR_COUNT_RW 2
#define IDE_BANK0_CYLINDER_LSB 4 #define IDE_CS0_SECTOR_NUMBER_RW 3
#define IDE_BANK0_CYLINDER_MSB 5 #define IDE_CS0_CYLINDER_LOW_RW 4
#define IDE_BANK0_HEAD_NUMBER 6 #define IDE_CS0_CYLINDER_HIGH_RW 5
#define IDE_BANK0_STATUS_COMMAND 7 #define IDE_CS0_DEVICE_HEAD_RW 6
#define IDE_CS0_STATUS_R 7
#define IDE_CS0_COMMAND_W 7
#define IDE_BANK1_STATUS_CONTROL 6 #define IDE_CS1_ALTERNATE_STATUS_R 6
#define IDE_CS1_DEVICE_CONTROL_W 6
#define IDE_COMMAND_READ_SECTORS 0x20 #define IDE_COMMAND_READ_SECTORS 0x20
#define IDE_COMMAND_READ_SECTORS_NORETRY 0x21 #define IDE_COMMAND_READ_SECTORS_NORETRY 0x21
@ -90,27 +93,38 @@ ide_mass_storage_device::ide_mass_storage_device(const machine_config &mconfig,
ide_device_interface(mconfig, *this), ide_device_interface(mconfig, *this),
device_slot_card_interface(mconfig, *this), device_slot_card_interface(mconfig, *this),
m_csel(0), m_csel(0),
m_dasp(0) m_dasp(0),
m_dmack(0),
m_dmarq(0),
m_irq(0)
{ {
} }
void ide_mass_storage_device::set_irq(int state) void ide_mass_storage_device::set_irq(int state)
{ {
if (m_irq != state)
{
m_irq = state;
if (state == ASSERT_LINE) if (state == ASSERT_LINE)
LOG(("IDE interrupt assert\n")); LOG(("IDE interrupt assert\n"));
else else
LOG(("IDE interrupt clear\n")); LOG(("IDE interrupt clear\n"));
m_interrupt_pending = state;
/* signal an interrupt */ /* signal an interrupt */
m_irq_handler(state); m_irq_handler(state);
} }
}
void ide_mass_storage_device::set_dmarq(int state) void ide_mass_storage_device::set_dmarq(int state)
{ {
if (m_dmarq != state)
{
m_dmarq = state;
m_dmarq_handler(state); m_dmarq_handler(state);
} }
}
WRITE_LINE_MEMBER( ide_mass_storage_device::write_csel ) WRITE_LINE_MEMBER( ide_mass_storage_device::write_csel )
{ {
@ -122,6 +136,11 @@ WRITE_LINE_MEMBER( ide_mass_storage_device::write_dasp )
m_dasp = state; m_dasp = state;
} }
WRITE_LINE_MEMBER( ide_mass_storage_device::write_dmack )
{
m_dmack = state;
}
/************************************* /*************************************
* *
* Compute the LBA address * Compute the LBA address
@ -340,11 +359,12 @@ void ide_mass_storage_device::device_start()
save_item(NAME(m_command)); save_item(NAME(m_command));
save_item(NAME(m_error)); save_item(NAME(m_error));
save_item(NAME(m_adapter_control)); save_item(NAME(m_device_control));
save_item(NAME(m_precomp_offset)); save_item(NAME(m_feature));
save_item(NAME(m_sector_count)); save_item(NAME(m_sector_count));
save_item(NAME(m_interrupt_pending)); save_item(NAME(m_irq));
save_item(NAME(m_dmarq));
save_item(NAME(m_sectors_until_int)); save_item(NAME(m_sectors_until_int));
save_item(NAME(m_master_password_enable)); save_item(NAME(m_master_password_enable));
@ -368,7 +388,13 @@ void ide_mass_storage_device::device_reset()
m_master_password_enable = (m_master_password != NULL); m_master_password_enable = (m_master_password != NULL);
m_user_password_enable = (m_user_password != NULL); m_user_password_enable = (m_user_password != NULL);
m_error = IDE_ERROR_DEFAULT; m_error = IDE_ERROR_DEFAULT;
m_status = IDE_STATUS_DRIVE_READY | IDE_STATUS_SEEK_COMPLETE;
m_status = IDE_STATUS_DSC;
if (is_ready())
{
m_status |= IDE_STATUS_DRDY;
}
m_cur_drive = 0; m_cur_drive = 0;
/* reset the drive state */ /* reset the drive state */
@ -381,13 +407,14 @@ void ide_mass_storage_device::device_timer(emu_timer &timer, device_timer_id id,
switch(id) switch(id)
{ {
case TID_DELAYED_INTERRUPT: case TID_DELAYED_INTERRUPT:
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
break; break;
case TID_DELAYED_INTERRUPT_BUFFER_READY: case TID_DELAYED_INTERRUPT_BUFFER_READY:
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
break; break;
@ -397,8 +424,8 @@ void ide_mass_storage_device::device_timer(emu_timer &timer, device_timer_id id,
case TID_SECURITY_ERROR_DONE: case TID_SECURITY_ERROR_DONE:
/* clear error state */ /* clear error state */
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_status |= IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_DRDY;
break; break;
case TID_READ_SECTOR_DONE_CALLBACK: case TID_READ_SECTOR_DONE_CALLBACK:
@ -414,8 +441,8 @@ void ide_mass_storage_device::device_timer(emu_timer &timer, device_timer_id id,
void ide_mass_storage_device::signal_delayed_interrupt(attotime time, int buffer_ready) void ide_mass_storage_device::signal_delayed_interrupt(attotime time, int buffer_ready)
{ {
/* clear buffer ready and set the busy flag */ /* clear buffer ready and set the busy flag */
m_status &= ~IDE_STATUS_BUFFER_READY; m_status &= ~IDE_STATUS_DRQ;
m_status |= IDE_STATUS_BUSY; m_status |= IDE_STATUS_BSY;
/* set a timer */ /* set a timer */
if (buffer_ready) if (buffer_ready)
@ -476,8 +503,8 @@ void ide_mass_storage_device::next_sector()
void ide_mass_storage_device::security_error() void ide_mass_storage_device::security_error()
{ {
/* set error state */ /* set error state */
m_status |= IDE_STATUS_ERROR; m_status |= IDE_STATUS_ERR;
m_status &= ~IDE_STATUS_DRIVE_READY; m_status &= ~IDE_STATUS_DRDY;
/* just set a timer and mark ourselves error */ /* just set a timer and mark ourselves error */
timer_set(TIME_SECURITY_ERROR, TID_SECURITY_ERROR_DONE); timer_set(TIME_SECURITY_ERROR, TID_SECURITY_ERROR_DONE);
@ -497,8 +524,8 @@ void ide_mass_storage_device::read_buffer_empty()
m_buffer_offset = 0; m_buffer_offset = 0;
/* clear the buffer ready and busy flag */ /* clear the buffer ready and busy flag */
m_status &= ~IDE_STATUS_BUFFER_READY; m_status &= ~IDE_STATUS_DRQ;
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
m_error = IDE_ERROR_DEFAULT; m_error = IDE_ERROR_DEFAULT;
set_dmarq(CLEAR_LINE); set_dmarq(CLEAR_LINE);
@ -525,8 +552,8 @@ void ide_mass_storage_device::read_sector_done()
/* GNET readlock check */ /* GNET readlock check */
if (m_gnetreadlock) { if (m_gnetreadlock) {
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
return; return;
} }
@ -535,12 +562,13 @@ void ide_mass_storage_device::read_sector_done()
/* by default, mark the buffer ready and the seek complete */ /* by default, mark the buffer ready and the seek complete */
if (!m_verify_only) if (!m_verify_only)
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
m_status |= IDE_STATUS_SEEK_COMPLETE;
m_status |= IDE_STATUS_DSC;
/* and clear the busy and error flags */ /* and clear the busy and error flags */
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
/* if we succeeded, advance to the next sector and set the nice bits */ /* if we succeeded, advance to the next sector and set the nice bits */
if (count == 1) if (count == 1)
@ -575,7 +603,7 @@ void ide_mass_storage_device::read_sector_done()
else else
{ {
/* set the error flag and the error */ /* set the error flag and the error */
m_status |= IDE_STATUS_ERROR; m_status |= IDE_STATUS_ERR;
m_error = IDE_ERROR_BAD_SECTOR; m_error = IDE_ERROR_BAD_SECTOR;
/* signal an interrupt */ /* signal an interrupt */
@ -587,7 +615,7 @@ void ide_mass_storage_device::read_sector_done()
void ide_mass_storage_device::read_first_sector() void ide_mass_storage_device::read_first_sector()
{ {
/* mark ourselves busy */ /* mark ourselves busy */
m_status |= IDE_STATUS_BUSY; m_status |= IDE_STATUS_BSY;
/* just set a timer */ /* just set a timer */
if (m_command == IDE_COMMAND_READ_MULTIPLE) if (m_command == IDE_COMMAND_READ_MULTIPLE)
@ -611,7 +639,7 @@ void ide_mass_storage_device::read_first_sector()
void ide_mass_storage_device::read_next_sector() void ide_mass_storage_device::read_next_sector()
{ {
/* mark ourselves busy */ /* mark ourselves busy */
m_status |= IDE_STATUS_BUSY; m_status |= IDE_STATUS_BSY;
if (m_command == IDE_COMMAND_READ_MULTIPLE) if (m_command == IDE_COMMAND_READ_MULTIPLE)
{ {
@ -641,8 +669,8 @@ void ide_mass_storage_device::continue_write()
m_buffer_offset = 0; m_buffer_offset = 0;
/* clear the buffer ready flag */ /* clear the buffer ready flag */
m_status &= ~IDE_STATUS_BUFFER_READY; m_status &= ~IDE_STATUS_DRQ;
m_status |= IDE_STATUS_BUSY; m_status |= IDE_STATUS_BSY;
if (m_command == IDE_COMMAND_WRITE_MULTIPLE) if (m_command == IDE_COMMAND_WRITE_MULTIPLE)
{ {
@ -668,6 +696,7 @@ void ide_mass_storage_device::continue_write()
void ide_mass_storage_device::write_buffer_full() void ide_mass_storage_device::write_buffer_full()
{ {
set_dmarq(CLEAR_LINE); set_dmarq(CLEAR_LINE);
if (m_command == IDE_COMMAND_SECURITY_UNLOCK) if (m_command == IDE_COMMAND_SECURITY_UNLOCK)
{ {
if (m_user_password_enable && memcmp(m_buffer, m_user_password, 2 + 32) == 0) if (m_user_password_enable && memcmp(m_buffer, m_user_password, 2 + 32) == 0)
@ -696,14 +725,14 @@ void ide_mass_storage_device::write_buffer_full()
} }
/* clear the busy and error flags */ /* clear the busy and error flags */
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
m_status &= ~IDE_STATUS_BUFFER_READY; m_status &= ~IDE_STATUS_DRQ;
if (m_master_password_enable || m_user_password_enable) if (m_master_password_enable || m_user_password_enable)
security_error(); security_error();
else else
m_status |= IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_DRDY;
} }
else if (m_command == IDE_COMMAND_TAITO_GNET_UNLOCK_2) else if (m_command == IDE_COMMAND_TAITO_GNET_UNLOCK_2)
{ {
@ -714,12 +743,12 @@ void ide_mass_storage_device::write_buffer_full()
for (i=0; !bad && i<512; i++) 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]); bad = ((i < 2 || i >= 7) && m_buffer[i]) || ((i >= 2 && i < 7) && m_buffer[i] != key[i-2]);
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
m_status &= ~IDE_STATUS_BUFFER_READY; m_status &= ~IDE_STATUS_DRQ;
if (bad) if (bad)
m_status |= IDE_STATUS_ERROR; m_status |= IDE_STATUS_ERR;
else { else {
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_gnetreadlock= 0; m_gnetreadlock= 0;
} }
} }
@ -738,12 +767,12 @@ void ide_mass_storage_device::write_sector_done()
count = write_sector(lba, m_buffer); count = write_sector(lba, m_buffer);
/* by default, mark the buffer ready and the seek complete */ /* by default, mark the buffer ready and the seek complete */
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
m_status |= IDE_STATUS_SEEK_COMPLETE; m_status |= IDE_STATUS_DSC;
/* and clear the busy adn error flags */ /* and clear the busy adn error flags */
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
/* if we succeeded, advance to the next sector and set the nice bits */ /* if we succeeded, advance to the next sector and set the nice bits */
if (count == 1) if (count == 1)
@ -767,7 +796,7 @@ void ide_mass_storage_device::write_sector_done()
if (m_sector_count > 0) if (m_sector_count > 0)
m_sector_count--; m_sector_count--;
if (m_sector_count == 0) if (m_sector_count == 0)
m_status &= ~IDE_STATUS_BUFFER_READY; m_status &= ~IDE_STATUS_DRQ;
/* keep going for DMA */ /* keep going for DMA */
if (m_dma_active && m_sector_count != 0) if (m_dma_active && m_sector_count != 0)
@ -780,7 +809,7 @@ void ide_mass_storage_device::write_sector_done()
else else
{ {
/* set the error flag and the error */ /* set the error flag and the error */
m_status |= IDE_STATUS_ERROR; m_status |= IDE_STATUS_ERR;
m_error = IDE_ERROR_BAD_SECTOR; m_error = IDE_ERROR_BAD_SECTOR;
/* signal an interrupt */ /* signal an interrupt */
@ -796,14 +825,14 @@ void ide_mass_storage_device::write_sector_done()
* *
*************************************/ *************************************/
void ide_mass_storage_device::handle_command(UINT8 _command) void ide_mass_storage_device::handle_command()
{ {
UINT8 key[5]; UINT8 key[5];
/* implicitly clear interrupts & dmarq here */ /* implicitly clear interrupts & dmarq here */
set_irq(CLEAR_LINE); set_irq(CLEAR_LINE);
set_dmarq(CLEAR_LINE); set_dmarq(CLEAR_LINE);
m_command = _command;
switch (m_command) switch (m_command)
{ {
case IDE_COMMAND_READ_SECTORS: case IDE_COMMAND_READ_SECTORS:
@ -875,7 +904,7 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
m_dma_active = 0; m_dma_active = 0;
/* mark the buffer ready */ /* mark the buffer ready */
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
break; break;
case IDE_COMMAND_WRITE_MULTIPLE: case IDE_COMMAND_WRITE_MULTIPLE:
@ -888,7 +917,7 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
m_dma_active = 0; m_dma_active = 0;
/* mark the buffer ready */ /* mark the buffer ready */
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
break; break;
case IDE_COMMAND_WRITE_DMA: case IDE_COMMAND_WRITE_DMA:
@ -900,6 +929,9 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
m_sectors_until_int = m_sector_count; m_sectors_until_int = m_sector_count;
m_dma_active = 1; m_dma_active = 1;
/* mark the buffer ready */
m_status |= IDE_STATUS_DRQ;
/* start the read going */ /* start the read going */
set_dmarq(ASSERT_LINE); set_dmarq(ASSERT_LINE);
break; break;
@ -913,7 +945,8 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
m_dma_active = 0; m_dma_active = 0;
/* mark the buffer ready */ /* mark the buffer ready */
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
break; break;
@ -928,13 +961,13 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
memcpy(m_buffer, m_features, sizeof(m_buffer)); memcpy(m_buffer, m_features, sizeof(m_buffer));
/* indicate everything is ready */ /* indicate everything is ready */
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
m_status |= IDE_STATUS_SEEK_COMPLETE; m_status |= IDE_STATUS_DSC;
m_status |= IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_DRDY;
/* and clear the busy adn error flags */ /* and clear the busy adn error flags */
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_status &= ~IDE_STATUS_BUSY; m_status &= ~IDE_STATUS_BSY;
/* clear the error too */ /* clear the error too */
m_error = IDE_ERROR_NONE; m_error = IDE_ERROR_NONE;
@ -969,7 +1002,7 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
case IDE_COMMAND_SET_CONFIG: case IDE_COMMAND_SET_CONFIG:
LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", m_cur_head + 1, m_sector_count)); LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", m_cur_head + 1, m_sector_count));
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
m_error = IDE_ERROR_NONE; m_error = IDE_ERROR_NONE;
set_geometry(m_sector_count,m_cur_head + 1); set_geometry(m_sector_count,m_cur_head + 1);
@ -986,7 +1019,7 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
break; break;
case IDE_COMMAND_SET_FEATURES: case IDE_COMMAND_SET_FEATURES:
LOGPRINT(("IDE Set features (%02X %02X %02X %02X %02X)\n", m_precomp_offset, m_sector_count & 0xff, m_cur_sector, m_cur_cylinder & 0xff, m_cur_cylinder >> 8)); 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 an interrupt */
signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0); signal_delayed_interrupt(MINIMUM_COMMAND_TIME, 0);
@ -997,7 +1030,7 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
m_block_count = m_sector_count; m_block_count = m_sector_count;
// judge dredd wants 'drive ready' on this command // judge dredd wants 'drive ready' on this command
m_status |= IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_DRDY;
/* signal an interrupt */ /* signal an interrupt */
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
@ -1007,8 +1040,8 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
LOGPRINT(("IDE GNET Unlock 1\n")); LOGPRINT(("IDE GNET Unlock 1\n"));
m_sector_count = 1; m_sector_count = 1;
m_status |= IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_DRDY;
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
break; break;
@ -1021,7 +1054,8 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
m_dma_active = 0; m_dma_active = 0;
/* mark the buffer ready */ /* mark the buffer ready */
m_status |= IDE_STATUS_BUFFER_READY; m_status |= IDE_STATUS_DRQ;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
break; break;
@ -1030,14 +1064,14 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
/* key check */ /* key check */
read_key(key); read_key(key);
if ((m_precomp_offset == key[0]) && (m_sector_count == key[1]) && (m_cur_sector == key[2]) && (m_cur_cylinder == (((UINT16)key[4]<<8)|key[3]))) 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; m_gnetreadlock= 0;
} }
/* update flags */ /* update flags */
m_status |= IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_DRDY;
m_status &= ~IDE_STATUS_ERROR; m_status &= ~IDE_STATUS_ERR;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
break; break;
@ -1059,7 +1093,7 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
default: default:
LOGPRINT(("IDE unknown command (%02X)\n", m_command)); LOGPRINT(("IDE unknown command (%02X)\n", m_command));
m_status |= IDE_STATUS_ERROR; m_status |= IDE_STATUS_ERR;
m_error = IDE_ERROR_UNKNOWN_COMMAND; m_error = IDE_ERROR_UNKNOWN_COMMAND;
set_irq(ASSERT_LINE); set_irq(ASSERT_LINE);
//debugger_break(device->machine()); //debugger_break(device->machine());
@ -1069,15 +1103,29 @@ void ide_mass_storage_device::handle_command(UINT8 _command)
UINT16 ide_mass_storage_device::read_dma() UINT16 ide_mass_storage_device::read_dma()
{ {
if (m_cur_drive != m_csel) UINT16 result = 0xffff;
if (device_selected())
{ {
if (m_csel == 0 && m_dasp == 0) if (!m_dmack)
return 0; {
logerror( "%s: read_dma ignored (!DMACK)\n", machine().describe_context() );
return 0xffff;
} }
else if( !m_dmarq)
UINT16 result = m_buffer[m_buffer_offset++]; {
logerror( "%s: read_dma ignored (!DMARQ)\n", machine().describe_context() );
}
else if (m_status & IDE_STATUS_BSY)
{
logerror( "%s: read_dma ignored (BSY)\n", machine().describe_context() );
}
else if (!(m_status & IDE_STATUS_DRQ))
{
logerror( "%s: read_dma ignored (!DRQ)\n", machine().describe_context() );
}
else
{
result = m_buffer[m_buffer_offset++];
result |= m_buffer[m_buffer_offset++] << 8; result |= m_buffer[m_buffer_offset++] << 8;
if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE)
@ -1085,37 +1133,61 @@ UINT16 ide_mass_storage_device::read_dma()
LOG(("%s:IDE completed DMA read\n", machine().describe_context())); LOG(("%s:IDE completed DMA read\n", machine().describe_context()));
read_buffer_empty(); read_buffer_empty();
} }
}
}
return result; return result;
} }
READ16_MEMBER( ide_mass_storage_device::read_cs0 ) READ16_MEMBER( ide_mass_storage_device::read_cs0 )
{ {
UINT16 result = 0;
/* logit */ /* logit */
// if (offset != IDE_BANK0_DATA && offset != IDE_BANK0_STATUS_COMMAND) // if (offset != IDE_CS0_DATA_RW && offset != IDE_CS0_STATUS_R)
LOG(("%s:IDE cs0 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask)); LOG(("%s:IDE cs0 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask));
if (m_cur_drive != m_csel) UINT16 result = 0xffff;
if (device_selected() || single_device())
{ {
if (m_csel == 0 && m_dasp == 0) if (m_dmack)
return 0; {
logerror( "%s: read_cs0 %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, mem_mask );
return 0xffff;
} }
else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_STATUS_R)
{
if (device_selected())
{
switch (offset)
{
case IDE_CS0_DATA_RW:
logerror( "%s: read_cs0 %04x %04x ignored (BSY)\n", machine().describe_context(), offset, mem_mask );
break;
if (is_ready()) { default:
m_status |= IDE_STATUS_DRIVE_READY; result = m_status;
} else {
m_status &= ~IDE_STATUS_DRIVE_READY; if (m_last_status_timer->elapsed() > TIME_PER_ROTATION)
{
result |= IDE_STATUS_IDX;
m_last_status_timer->adjust(attotime::never);
} }
break;
}
}
else
{
result = 0;
}
}
else
{
switch (offset) switch (offset)
{ {
/* read data if there's data to be read */ /* read data if there's data to be read */
case IDE_BANK0_DATA: case IDE_CS0_DATA_RW:
if (m_status & IDE_STATUS_BUFFER_READY) if (device_selected())
{
if (m_status & IDE_STATUS_DRQ)
{ {
/* fetch the correct amount of data */ /* fetch the correct amount of data */
result = m_buffer[m_buffer_offset++]; result = m_buffer[m_buffer_offset++];
@ -1129,48 +1201,61 @@ READ16_MEMBER( ide_mass_storage_device::read_cs0 )
read_buffer_empty(); read_buffer_empty();
} }
} }
}
else
{
result = 0;
}
break; break;
/* return the current error */ /* return the current error */
case IDE_BANK0_ERROR: case IDE_CS0_ERROR_R:
result = m_error; result = m_error;
break; break;
/* return the current sector count */ /* return the current sector count */
case IDE_BANK0_SECTOR_COUNT: case IDE_CS0_SECTOR_COUNT_RW:
result = m_sector_count; result = m_sector_count;
break; break;
/* return the current sector */ /* return the current sector */
case IDE_BANK0_SECTOR_NUMBER: case IDE_CS0_SECTOR_NUMBER_RW:
result = m_cur_sector; result = m_cur_sector;
break; break;
/* return the current cylinder LSB */ /* return the current cylinder LSB */
case IDE_BANK0_CYLINDER_LSB: case IDE_CS0_CYLINDER_LOW_RW:
result = m_cur_cylinder & 0xff; result = m_cur_cylinder & 0xff;
break; break;
/* return the current cylinder MSB */ /* return the current cylinder MSB */
case IDE_BANK0_CYLINDER_MSB: case IDE_CS0_CYLINDER_HIGH_RW:
result = m_cur_cylinder >> 8; result = m_cur_cylinder >> 8;
break; break;
/* return the current head */ /* return the current head */
case IDE_BANK0_HEAD_NUMBER: case IDE_CS0_DEVICE_HEAD_RW:
result = m_cur_head_reg; result = m_cur_head_reg;
break; break;
/* return the current status and clear any pending interrupts */ /* return the current status and clear any pending interrupts */
case IDE_BANK0_STATUS_COMMAND: case IDE_CS0_STATUS_R:
if (device_selected())
{
result = m_status; result = m_status;
if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) if (m_last_status_timer->elapsed() > TIME_PER_ROTATION)
{ {
result |= IDE_STATUS_HIT_INDEX; result |= IDE_STATUS_IDX;
m_last_status_timer->adjust(attotime::never); m_last_status_timer->adjust(attotime::never);
} }
if (m_interrupt_pending == ASSERT_LINE)
set_irq(CLEAR_LINE); set_irq(CLEAR_LINE);
}
else
{
result = 0;
}
break; break;
/* log anything else */ /* log anything else */
@ -1178,6 +1263,8 @@ READ16_MEMBER( ide_mass_storage_device::read_cs0 )
logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask);
break; break;
} }
}
}
/* return the result */ /* return the result */
return result; return result;
@ -1185,36 +1272,37 @@ READ16_MEMBER( ide_mass_storage_device::read_cs0 )
READ16_MEMBER( ide_mass_storage_device::read_cs1 ) READ16_MEMBER( ide_mass_storage_device::read_cs1 )
{ {
if (m_cur_drive != m_csel)
{
if (m_csel == 0 && m_dasp == 0)
return 0;
return 0xffff;
}
if (is_ready()) {
m_status |= IDE_STATUS_DRIVE_READY;
} else {
m_status &= ~IDE_STATUS_DRIVE_READY;
}
/* logit */ /* logit */
// if (offset != IDE_BANK1_STATUS_CONTROL) // if (offset != IDE_CS1_ALTERNATE_STATUS_R)
LOG(("%s:IDE cs1 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask)); LOG(("%s:IDE cs1 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask));
/* return the current status but don't clear interrupts */
UINT16 result = 0; UINT16 result = 0xffff;
if (device_selected() || single_device())
{
if (m_dmack)
{
logerror( "%s: read_cs1 %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, mem_mask );
}
else
{
switch (offset) switch (offset)
{ {
case IDE_BANK1_STATUS_CONTROL: case IDE_CS1_ALTERNATE_STATUS_R:
if( device_selected() )
{
/* return the current status but don't clear interrupts */
result = m_status; result = m_status;
if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) if (m_last_status_timer->elapsed() > TIME_PER_ROTATION)
{ {
result |= IDE_STATUS_HIT_INDEX; result |= IDE_STATUS_IDX;
m_last_status_timer->adjust(attotime::never); m_last_status_timer->adjust(attotime::never);
} }
}
else
{
result = 0;
}
break; break;
/* log anything else */ /* log anything else */
@ -1222,6 +1310,8 @@ READ16_MEMBER( ide_mass_storage_device::read_cs1 )
logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask);
break; break;
} }
}
}
/* return the result */ /* return the result */
return result; return result;
@ -1229,9 +1319,26 @@ READ16_MEMBER( ide_mass_storage_device::read_cs1 )
void ide_mass_storage_device::write_dma( UINT16 data ) void ide_mass_storage_device::write_dma( UINT16 data )
{ {
if (m_cur_drive != m_csel) if (device_selected())
return; {
if (!m_dmack)
{
logerror( "%s: write_dma %04x ignored (!DMACK)\n", machine().describe_context(), data );
}
else if( !m_dmarq)
{
logerror( "%s: write_dma %04x ignored (!DMARQ)\n", machine().describe_context(), data );
}
else if (m_status & IDE_STATUS_BSY)
{
logerror( "%s: write_dma %04x ignored (BSY)\n", machine().describe_context(), data );
}
else if (!(m_status & IDE_STATUS_DRQ))
{
logerror( "%s: write_dma %04x ignored (!DRQ)\n", machine().describe_context(), data );
}
else
{
m_buffer[m_buffer_offset++] = data; m_buffer[m_buffer_offset++] = data;
m_buffer[m_buffer_offset++] = data >> 8; m_buffer[m_buffer_offset++] = data >> 8;
@ -1242,28 +1349,41 @@ void ide_mass_storage_device::write_dma( UINT16 data )
write_buffer_full(); write_buffer_full();
} }
} }
}
}
WRITE16_MEMBER( ide_mass_storage_device::write_cs0 ) WRITE16_MEMBER( ide_mass_storage_device::write_cs0 )
{ {
switch (offset)
{
case IDE_BANK0_HEAD_NUMBER:
m_cur_drive = (data & 0x10) >> 4;
break;
}
if (m_cur_drive != m_csel)
return;
/* logit */ /* logit */
if (offset != IDE_BANK0_DATA) 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)); LOG(("%s:IDE cs0 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask));
// fprintf(stderr, "ide write %03x %02x mem_mask=%d\n", offset, data, size); // fprintf(stderr, "ide write %03x %02x mem_mask=%d\n", offset, data, size);
if (m_dmack)
{
logerror( "%s: write_cs0 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, data, mem_mask );
}
else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_COMMAND_W)
{
logerror( "%s: write_cs0 %04x %04x %04x ignored (BSY)\n", machine().describe_context(), offset, data, mem_mask );
}
else if ((m_status & IDE_STATUS_DRQ) && offset != IDE_CS0_DATA_RW && offset != IDE_CS0_COMMAND_W)
{
logerror( "%s: write_cs0 %04x %04x %04x ignored (DRQ)\n", machine().describe_context(), offset, data, mem_mask );
}
else
{
switch (offset) switch (offset)
{ {
/* write data */ /* write data */
case IDE_BANK0_DATA: case IDE_CS0_DATA_RW:
if (m_status & IDE_STATUS_BUFFER_READY) if( device_selected() )
{
if (!(m_status & IDE_STATUS_DRQ))
{
logerror( "%s: write_cs0 %04x %04x %04x ignored (!DRQ)\n", machine().describe_context(), offset, data, mem_mask );
}
else
{ {
/* store the correct amount of data */ /* store the correct amount of data */
m_buffer[m_buffer_offset++] = data; m_buffer[m_buffer_offset++] = data;
@ -1277,72 +1397,86 @@ WRITE16_MEMBER( ide_mass_storage_device::write_cs0 )
write_buffer_full(); write_buffer_full();
} }
} }
}
break; break;
/* precompensation offset?? */ case IDE_CS0_FEATURE_W:
case IDE_BANK0_ERROR: m_feature = data;
m_precomp_offset = data;
break; break;
/* sector count */ /* sector count */
case IDE_BANK0_SECTOR_COUNT: case IDE_CS0_SECTOR_COUNT_RW:
m_sector_count = data ? data : 256; m_sector_count = data ? data : 256;
break; break;
/* current sector */ /* current sector */
case IDE_BANK0_SECTOR_NUMBER: case IDE_CS0_SECTOR_NUMBER_RW:
m_cur_sector = data; m_cur_sector = data;
break; break;
/* current cylinder LSB */ /* current cylinder LSB */
case IDE_BANK0_CYLINDER_LSB: case IDE_CS0_CYLINDER_LOW_RW:
m_cur_cylinder = (m_cur_cylinder & 0xff00) | (data & 0xff); m_cur_cylinder = (m_cur_cylinder & 0xff00) | (data & 0xff);
break; break;
/* current cylinder MSB */ /* current cylinder MSB */
case IDE_BANK0_CYLINDER_MSB: case IDE_CS0_CYLINDER_HIGH_RW:
m_cur_cylinder = (m_cur_cylinder & 0x00ff) | ((data & 0xff) << 8); m_cur_cylinder = ((data << 8) & 0xff00) | (m_cur_cylinder & 0xff);
break; break;
/* current head */ /* current head */
case IDE_BANK0_HEAD_NUMBER: case IDE_CS0_DEVICE_HEAD_RW:
// LBA mode = data & 0x40
m_cur_drive = (data & 0x10) >> 4;
m_cur_head = data & 0x0f; m_cur_head = data & 0x0f;
m_cur_head_reg = data; m_cur_head_reg = data;
// LBA mode = data & 0x40
break; break;
/* command */ /* command */
case IDE_BANK0_STATUS_COMMAND: case IDE_CS0_COMMAND_W:
handle_command(data); m_command = data;
if (device_selected() || m_command == IDE_COMMAND_DIAGNOSTIC)
handle_command();
break; break;
} }
} }
}
WRITE16_MEMBER( ide_mass_storage_device::write_cs1 ) WRITE16_MEMBER( ide_mass_storage_device::write_cs1 )
{ {
if (m_cur_drive != m_csel)
return;
/* logit */ /* logit */
LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask));
if (m_dmack)
{
logerror( "%s: write_cs1 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), offset, data, mem_mask );
}
else
{
switch (offset) switch (offset)
{ {
/* adapter control */ /* adapter control */
case IDE_BANK1_STATUS_CONTROL: case IDE_CS1_DEVICE_CONTROL_W:
m_adapter_control = data; 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 );
}
/* handle controller reset */
//if (data == 0x04)
if (data & 0x04) if (data & 0x04)
{ {
m_status |= IDE_STATUS_BUSY; // SRST
m_status &= ~IDE_STATUS_DRIVE_READY; m_status |= IDE_STATUS_BSY;
m_status &= ~IDE_STATUS_DRDY;
m_reset_timer->adjust(attotime::from_msec(5)); m_reset_timer->adjust(attotime::from_msec(5));
} }
break; break;
} }
} }
}
//************************************************************************** //**************************************************************************
// IDE HARD DISK DEVICE // IDE HARD DISK DEVICE
@ -1371,8 +1505,6 @@ ide_hdd_device::ide_hdd_device(const machine_config &mconfig, device_type type,
void ide_hdd_device::device_reset() void ide_hdd_device::device_reset()
{ {
ide_mass_storage_device::device_reset();
m_handle = subdevice<harddisk_image_device>("harddisk")->get_chd_file(); m_handle = subdevice<harddisk_image_device>("harddisk")->get_chd_file();
if (m_handle) if (m_handle)
@ -1385,6 +1517,8 @@ void ide_hdd_device::device_reset()
m_disk = hard_disk_open(m_handle); m_disk = hard_disk_open(m_handle);
} }
ide_mass_storage_device::device_reset();
if (m_disk != NULL) if (m_disk != NULL)
{ {
const hard_disk_info *hdinfo = hard_disk_get_info(m_disk); const hard_disk_info *hdinfo = hard_disk_get_info(m_disk);

View File

@ -3,12 +3,29 @@
#define IDE_DISK_SECTOR_SIZE 512 #define IDE_DISK_SECTOR_SIZE 512
#define IDE_STATUS_ERROR 0x01 // Error
#define IDE_STATUS_HIT_INDEX 0x02 #define IDE_STATUS_ERR (0x01)
#define IDE_STATUS_BUFFER_READY 0x08
#define IDE_STATUS_SEEK_COMPLETE 0x10 // Index
#define IDE_STATUS_DRIVE_READY 0x40 #define IDE_STATUS_IDX (0x02)
#define IDE_STATUS_BUSY 0x80
// Corrected Data
#define IDE_STATUS_CORR (0x04)
// Data Request
#define IDE_STATUS_DRQ (0x08)
// Drive Seek Complete
#define IDE_STATUS_DSC (0x10)
// Drive Write Fault
#define IDE_STATUS_DWF (0x20)
// Drive Ready
#define IDE_STATUS_DRDY (0x40)
// Busy
#define IDE_STATUS_BSY (0x80)
#define IDE_ERROR_NONE 0x00 #define IDE_ERROR_NONE 0x00
#define IDE_ERROR_DEFAULT 0x01 #define IDE_ERROR_DEFAULT 0x01
@ -32,6 +49,7 @@ public:
virtual void write_dma(UINT16 data) = 0; virtual void write_dma(UINT16 data) = 0;
virtual DECLARE_WRITE16_MEMBER(write_cs0) = 0; virtual DECLARE_WRITE16_MEMBER(write_cs0) = 0;
virtual DECLARE_WRITE16_MEMBER(write_cs1) = 0; virtual DECLARE_WRITE16_MEMBER(write_cs1) = 0;
virtual DECLARE_WRITE_LINE_MEMBER(write_dmack) = 0;
virtual DECLARE_WRITE_LINE_MEMBER(write_csel) = 0; virtual DECLARE_WRITE_LINE_MEMBER(write_csel) = 0;
virtual DECLARE_WRITE_LINE_MEMBER(write_dasp) = 0; virtual DECLARE_WRITE_LINE_MEMBER(write_dasp) = 0;
@ -62,6 +80,7 @@ public:
virtual DECLARE_WRITE16_MEMBER(write_cs1); virtual DECLARE_WRITE16_MEMBER(write_cs1);
virtual DECLARE_WRITE_LINE_MEMBER(write_csel); virtual DECLARE_WRITE_LINE_MEMBER(write_csel);
virtual DECLARE_WRITE_LINE_MEMBER(write_dasp); virtual DECLARE_WRITE_LINE_MEMBER(write_dasp);
virtual DECLARE_WRITE_LINE_MEMBER(write_dmack);
virtual UINT8 *get_features() { return m_features; } virtual UINT8 *get_features() { return m_features; }
@ -75,6 +94,9 @@ protected:
virtual bool is_ready() = 0; virtual bool is_ready() = 0;
virtual void read_key(UINT8 key[]) = 0; virtual void read_key(UINT8 key[]) = 0;
bool device_selected() { return m_cur_drive == m_csel; }
bool single_device() { return m_csel == 0 && m_dasp == 0; }
void set_irq(int state); void set_irq(int state);
void set_dmarq(int state); void set_dmarq(int state);
void ide_build_features(); void ide_build_features();
@ -98,12 +120,15 @@ private:
void security_error(); void security_error();
void continue_read(); void continue_read();
void read_first_sector(); void read_first_sector();
void handle_command(UINT8 _command); void handle_command();
void read_buffer_empty(); void read_buffer_empty();
void write_buffer_full(); void write_buffer_full();
int m_csel; int m_csel;
int m_dasp; int m_dasp;
int m_dmack;
int m_dmarq;
int m_irq;
int m_cur_drive; int m_cur_drive;
UINT16 m_cur_cylinder; UINT16 m_cur_cylinder;
@ -119,12 +144,11 @@ private:
UINT8 m_buffer[IDE_DISK_SECTOR_SIZE]; UINT8 m_buffer[IDE_DISK_SECTOR_SIZE];
UINT16 m_buffer_offset; UINT16 m_buffer_offset;
UINT8 m_adapter_control; UINT8 m_device_control;
UINT8 m_precomp_offset; UINT8 m_feature;
UINT16 m_sector_count; UINT16 m_sector_count;
UINT16 m_block_count; UINT16 m_block_count;
UINT8 m_interrupt_pending;
UINT16 m_sectors_until_int; UINT16 m_sectors_until_int;
UINT8 m_dma_active; UINT8 m_dma_active;

View File

@ -1338,11 +1338,13 @@ void zn_state::atpsx_dma_read( UINT32 *p_n_psxram, UINT32 n_address, INT32 n_siz
return; return;
} }
address_space &space = machine().firstcpu->space(AS_PROGRAM);
/* dma size is in 32-bit words, convert to words */ /* dma size is in 32-bit words, convert to words */
n_size <<= 1; n_size <<= 1;
while( n_size > 0 ) while( n_size > 0 )
{ {
psxwriteword( p_n_psxram, n_address, m_ide->read_dma() ); psxwriteword( p_n_psxram, n_address, m_ide->read_cs0(space, 0, 0xffff) );
n_address += 2; n_address += 2;
n_size--; n_size--;
} }