summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/idectrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/machine/idectrl.c')
-rw-r--r--src/emu/machine/idectrl.c443
1 files changed, 206 insertions, 237 deletions
diff --git a/src/emu/machine/idectrl.c b/src/emu/machine/idectrl.c
index fb30e24fa18..74b22e1bb26 100644
--- a/src/emu/machine/idectrl.c
+++ b/src/emu/machine/idectrl.c
@@ -42,22 +42,20 @@
#define IDE_STATUS_DRIVE_READY 0x40
#define IDE_STATUS_BUSY 0x80
-#define BANK(b, v) (((v) << 4) | (b))
+#define IDE_BANK0_DATA 0
+#define IDE_BANK0_ERROR 1
+#define IDE_BANK0_SECTOR_COUNT 2
+#define IDE_BANK0_SECTOR_NUMBER 3
+#define IDE_BANK0_CYLINDER_LSB 4
+#define IDE_BANK0_CYLINDER_MSB 5
+#define IDE_BANK0_HEAD_NUMBER 6
+#define IDE_BANK0_STATUS_COMMAND 7
-#define IDE_BANK0_DATA BANK(0, 0)
-#define IDE_BANK0_ERROR BANK(0, 1)
-#define IDE_BANK0_SECTOR_COUNT BANK(0, 2)
-#define IDE_BANK0_SECTOR_NUMBER BANK(0, 3)
-#define IDE_BANK0_CYLINDER_LSB BANK(0, 4)
-#define IDE_BANK0_CYLINDER_MSB BANK(0, 5)
-#define IDE_BANK0_HEAD_NUMBER BANK(0, 6)
-#define IDE_BANK0_STATUS_COMMAND BANK(0, 7)
+#define IDE_BANK1_STATUS_CONTROL 6
-#define IDE_BANK1_STATUS_CONTROL BANK(1, 6)
-
-#define IDE_BANK2_CONFIG_UNK BANK(2, 4)
-#define IDE_BANK2_CONFIG_REGISTER BANK(2, 8)
-#define IDE_BANK2_CONFIG_DATA BANK(2, 0xc)
+#define IDE_BANK2_CONFIG_UNK 4
+#define IDE_BANK2_CONFIG_REGISTER 8
+#define IDE_BANK2_CONFIG_DATA 0xc
#define IDE_COMMAND_READ_MULTIPLE 0x20
#define IDE_COMMAND_READ_MULTIPLE_NORETRY 0x21
@@ -226,20 +224,6 @@ INLINE int convert_to_offset_and_size32(offs_t *offset, UINT32 mem_mask)
return size;
}
-INLINE int convert_to_offset_and_size16(offs_t *offset, UINT32 mem_mask)
-{
- int size = 2;
-
- /* determine which real offset */
- if (!ACCESSING_BITS_0_7)
- (*offset)++, size = 1;
-
- if (ACCESSING_BITS_8_15)
- return size;
- size--;
- return size;
-}
-
/*************************************
@@ -968,14 +952,61 @@ void ide_controller_device::handle_command(UINT8 _command)
*
*************************************/
-UINT32 ide_controller_device::ide_controller_read(int bank, offs_t offset, int size)
+READ8_MEMBER( ide_controller_device::read_via_config )
{
- UINT32 result = 0;
+ UINT16 result = 0;
+
+ /* logit */
+ LOG(("%s:IDE via config read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask));
+
+ switch(offset)
+ {
+ /* unknown config register */
+ case IDE_BANK2_CONFIG_UNK:
+ result = config_unknown;
+ break;
+
+ /* active config register */
+ case IDE_BANK2_CONFIG_REGISTER:
+ result = config_register_num;
+ break;
+
+ /* data from active config register */
+ case IDE_BANK2_CONFIG_DATA:
+ if (config_register_num < IDE_CONFIG_REGISTERS)
+ result = config_register[config_register_num];
+ break;
+
+ default:
+ logerror("%s:unknown IDE via config read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask);
+ break;
+ }
+
+// printf( "read via config %04x %04x %04x\n", offset, result, mem_mask );
+ return result;
+}
+
+READ16_MEMBER( ide_controller_device::read_cs0_pc )
+{
+ if (mem_mask == 0xffff && offset == 1 ) offset = 0; // hack for 32 bit read of data register
+ if (mem_mask == 0xff00)
+ {
+ return read_cs0(space, (offset * 2) + 1, 0xff) << 8;
+ }
+ else
+ {
+ return read_cs0(space, offset * 2, mem_mask);
+ }
+}
+
+READ16_MEMBER( ide_controller_device::read_cs0 )
+{
+ UINT16 result = 0;
ide_device_interface *dev = slot[cur_drive]->dev();
/* logit */
-// if (BANK(bank, offset) != IDE_BANK0_DATA && BANK(bank, offset) != IDE_BANK0_STATUS_COMMAND && BANK(bank, offset) != IDE_BANK1_STATUS_CONTROL)
- LOG(("%s:IDE read at %d:%X, size=%d\n", machine().describe_context(), bank, offset, size));
+// if (offset != IDE_BANK0_DATA && offset != IDE_BANK0_STATUS_COMMAND)
+ LOG(("%s:IDE cs0 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask));
if (dev != NULL)
{
@@ -993,35 +1024,16 @@ UINT32 ide_controller_device::ide_controller_read(int bank, offs_t offset, int s
return status;
}
- switch (BANK(bank, offset))
+ switch (offset)
{
- /* unknown config register */
- case IDE_BANK2_CONFIG_UNK:
- return config_unknown;
-
- /* active config register */
- case IDE_BANK2_CONFIG_REGISTER:
- return config_register_num;
-
- /* data from active config register */
- case IDE_BANK2_CONFIG_DATA:
- if (config_register_num < IDE_CONFIG_REGISTERS)
- return config_register[config_register_num];
- return 0;
-
/* read data if there's data to be read */
case IDE_BANK0_DATA:
if (status & IDE_STATUS_BUFFER_READY)
{
/* fetch the correct amount of data */
result = buffer[buffer_offset++];
- if (size > 1)
+ if (mem_mask == 0xffff)
result |= buffer[buffer_offset++] << 8;
- if (size > 2)
- {
- result |= buffer[buffer_offset++] << 16;
- result |= buffer[buffer_offset++] << 24;
- }
/* if we're at the end of the buffer, handle it */
if (buffer_offset >= IDE_DISK_SECTOR_SIZE)
@@ -1035,83 +1047,135 @@ UINT32 ide_controller_device::ide_controller_read(int bank, offs_t offset, int s
/* return the current error */
case IDE_BANK0_ERROR:
- return error;
+ result = error;
+ break;
/* return the current sector count */
case IDE_BANK0_SECTOR_COUNT:
- return sector_count;
+ result = sector_count;
+ break;
/* return the current sector */
case IDE_BANK0_SECTOR_NUMBER:
- return dev->cur_sector;
+ result = dev->cur_sector;
+ break;
/* return the current cylinder LSB */
case IDE_BANK0_CYLINDER_LSB:
- return dev->cur_cylinder & 0xff;
+ result = dev->cur_cylinder & 0xff;
+ break;
/* return the current cylinder MSB */
case IDE_BANK0_CYLINDER_MSB:
- return dev->cur_cylinder >> 8;
+ result = dev->cur_cylinder >> 8;
+ break;
/* return the current head */
case IDE_BANK0_HEAD_NUMBER:
- return dev->cur_head_reg;
+ result = dev->cur_head_reg;
+ break;
/* return the current status and clear any pending interrupts */
case IDE_BANK0_STATUS_COMMAND:
- /* return the current status but don't clear interrupts */
- case IDE_BANK1_STATUS_CONTROL:
result = status;
if (last_status_timer->elapsed() > TIME_PER_ROTATION)
{
result |= IDE_STATUS_HIT_INDEX;
last_status_timer->adjust(attotime::never);
}
+ if (interrupt_pending)
+ clear_interrupt();
+ break;
+
+ /* log anything else */
+ default:
+ logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask);
+ break;
+ }
+
+// printf( "read cs0 %04x %04x %04x\n", offset, result, mem_mask );
+
+ /* return the result */
+ return result;
+}
+
+
+READ16_MEMBER( ide_controller_device::read_cs1_pc )
+{
+ if (mem_mask == 0xff00)
+ {
+ return read_cs1(space, (offset * 2) + 1, 0xff) << 8;
+ }
+ else
+ {
+ return read_cs1(space, offset * 2, mem_mask);
+ }
+}
+
+READ16_MEMBER( ide_controller_device::read_cs1 )
+{
+ UINT16 result = 0;
+ ide_device_interface *dev = slot[cur_drive]->dev();
+
+ if (dev != NULL)
+ {
+ if (dev->is_ready()) {
+ status |= IDE_STATUS_DRIVE_READY;
+ } else {
+ status &= ~IDE_STATUS_DRIVE_READY;
+ }
+ }
+ else
+ {
+ /* even a do-nothing operation should take a little time */
+
+ status ^= IDE_STATUS_BUSY;
+ return status;
+ }
+
+ /* logit */
+// if (offset != IDE_BANK1_STATUS_CONTROL)
+ 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 */
- /* clear interrutps only when reading the real status */
- if (BANK(bank, offset) == IDE_BANK0_STATUS_COMMAND)
+ switch (offset)
+ {
+ case IDE_BANK1_STATUS_CONTROL:
+ result = status;
+ if (last_status_timer->elapsed() > TIME_PER_ROTATION)
{
- if (interrupt_pending)
- clear_interrupt();
+ result |= IDE_STATUS_HIT_INDEX;
+ last_status_timer->adjust(attotime::never);
}
break;
/* log anything else */
default:
- logerror("%s:unknown IDE read at %03X, size=%d\n", machine().describe_context(), offset, size);
+ logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask);
break;
}
+// printf( "read cs1 %04x %04x %04x\n", offset, result, mem_mask );
+
/* return the result */
return result;
}
-
/*************************************
*
* IDE controller write
*
*************************************/
-void ide_controller_device::ide_controller_write(int bank, offs_t offset, int size, UINT32 data)
+WRITE8_MEMBER( ide_controller_device::write_via_config )
{
- switch (BANK(bank, offset))
- {
- case IDE_BANK0_HEAD_NUMBER:
- cur_drive = (data & 0x10) >> 4;
- break;
- }
-
- ide_device_interface *dev = slot[cur_drive]->dev();
- if (dev == NULL)
- return;
+// printf( "write via config %04x %04x %04x\n", offset, data, mem_mask );
/* logit */
- if (BANK(bank, offset) != IDE_BANK0_DATA)
- LOG(("%s:IDE write to %d:%X = %08X, size=%d\n", machine().describe_context(), bank, offset, data, size));
- // fprintf(stderr, "ide write %03x %02x size=%d\n", offset, data, size);
- switch (BANK(bank, offset))
+ LOG(("%s:IDE via config write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask));
+
+ switch (offset)
{
/* unknown config register */
case IDE_BANK2_CONFIG_UNK:
@@ -1128,20 +1192,51 @@ void ide_controller_device::ide_controller_write(int bank, offs_t offset, int si
if (config_register_num < IDE_CONFIG_REGISTERS)
config_register[config_register_num] = data;
break;
+ }
+}
+
+WRITE16_MEMBER( ide_controller_device::write_cs0_pc )
+{
+ if (mem_mask == 0xffff && offset == 1 ) offset = 0; // hack for 32 bit write to data register
+ if (mem_mask == 0xff00)
+ {
+ return write_cs0(space, (offset * 2) + 1, data >> 8, 0xff);
+ }
+ else
+ {
+ return write_cs0(space, offset * 2, data, mem_mask);
+ }
+}
+
+WRITE16_MEMBER( ide_controller_device::write_cs0 )
+{
+// printf( "write cs0 %04x %04x %04x\n", offset, data, mem_mask );
+ switch (offset)
+ {
+ case IDE_BANK0_HEAD_NUMBER:
+ cur_drive = (data & 0x10) >> 4;
+ break;
+ }
+
+ ide_device_interface *dev = slot[cur_drive]->dev();
+ if (dev == NULL)
+ return;
+
+ /* logit */
+ if (offset != IDE_BANK0_DATA)
+ 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);
+ switch (offset)
+ {
/* write data */
case IDE_BANK0_DATA:
if (status & IDE_STATUS_BUFFER_READY)
{
/* store the correct amount of data */
buffer[buffer_offset++] = data;
- if (size > 1)
+ if (mem_mask == 0xffff)
buffer[buffer_offset++] = data >> 8;
- if (size > 2)
- {
- buffer[buffer_offset++] = data >> 16;
- buffer[buffer_offset++] = data >> 24;
- }
/* if we're at the end of the buffer, handle it */
if (buffer_offset >= IDE_DISK_SECTOR_SIZE)
@@ -1245,7 +1340,30 @@ void ide_controller_device::ide_controller_write(int bank, offs_t offset, int si
case IDE_BANK0_STATUS_COMMAND:
handle_command(data);
break;
+ }
+}
+
+WRITE16_MEMBER( ide_controller_device::write_cs1_pc )
+{
+ if (mem_mask == 0xff00)
+ {
+ return write_cs1(space, (offset * 2) + 1, data >> 8, 0xff);
+ }
+ else
+ {
+ return write_cs1(space, offset * 2, data, mem_mask);
+ }
+}
+
+WRITE16_MEMBER( ide_controller_device::write_cs1 )
+{
+// printf( "write cs1 %04x %04x %04x\n", offset, data, mem_mask );
+
+ /* logit */
+ LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask));
+ switch (offset)
+ {
/* adapter control */
case IDE_BANK1_STATUS_CONTROL:
adapter_control = data;
@@ -1263,7 +1381,6 @@ void ide_controller_device::ide_controller_write(int bank, offs_t offset, int si
}
-
/*************************************
*
* Bus master read
@@ -1354,126 +1471,6 @@ void ide_controller_device::ide_bus_master_write(offs_t offset, int size, UINT32
bus_master_descriptor = data & 0xfffffffc;
}
-
-
-/*************************************
- *
- * IDE direct handlers (16-bit)
- *
- *************************************/
-
-/*
- ide_bus_r()
-
- Read a 16-bit word from the IDE bus directly.
-
- select: 0->CS1Fx active, 1->CS3Fx active
- offset: register offset (state of DA2-DA0)
-*/
-int ide_controller_device::ide_bus_r(int select, int offset)
-{
- return ide_controller_read(select ? 1 : 0, offset, select == 0 && offset == 0 ? 2 : 1);
-}
-
-/*
- ide_bus_w()
-
- Write a 16-bit word to the IDE bus directly.
-
- select: 0->CS1Fx active, 1->CS3Fx active
- offset: register offset (state of DA2-DA0)
- data: data written (state of D0-D15 or D0-D7)
-*/
-void ide_controller_device::ide_bus_w(int select, int offset, int data)
-{
- if (select == 0 && offset == 0)
- ide_controller_write(0, 0, 2, data);
- else
- ide_controller_write(select ? 1 : 0, offset, 1, data & 0xff);
-}
-
-UINT32 ide_controller_device::ide_controller_r(int reg, int size)
-{
- if (reg >= 0x1f0 && reg < 0x1f8)
- return ide_controller_read(0, reg & 7, size);
- if (reg >= 0x3f0 && reg < 0x3f8)
- return ide_controller_read(1, reg & 7, size);
- if (reg >= 0x030 && reg < 0x040)
- return ide_controller_read(2, reg & 0xf, size);
- return 0xffffffff;
-}
-
-void ide_controller_device::ide_controller_w(int reg, int size, UINT32 data)
-{
- if (reg >= 0x1f0 && reg < 0x1f8)
- ide_controller_write(0, reg & 7, size, data);
- if (reg >= 0x3f0 && reg < 0x3f8)
- ide_controller_write(1, reg & 7, size, data);
- if (reg >= 0x030 && reg < 0x040)
- ide_controller_write(2, reg & 0xf, size, data);
-}
-
-
-/*************************************
- *
- * 32-bit IDE handlers
- *
- *************************************/
-
-READ32_MEMBER( ide_controller_device::ide_controller32_r )
-{
- int size;
-
- offset *= 4;
- size = convert_to_offset_and_size32(&offset, mem_mask);
-
- return ide_controller_r(offset, size) << ((offset & 3) * 8);
-}
-
-
-WRITE32_MEMBER( ide_controller_device::ide_controller32_w )
-{
- int size;
-
- offset *= 4;
- size = convert_to_offset_and_size32(&offset, mem_mask);
- data = data >> ((offset & 3) * 8);
-
- ide_controller_w(offset, size, data);
-}
-
-
-READ16_MEMBER( ide_controller_device::ide_controller16_pcmcia_r )
-{
- int size;
- UINT32 res = 0xffff;
-
- offset *= 2;
- size = convert_to_offset_and_size16(&offset, mem_mask);
-
- if (offset < 0x008)
- res = ide_controller_read(0, offset & 7, size);
- if (offset >= 0x008 && offset < 0x010)
- res = ide_controller_read(1, offset & 7, size);
-
- return res << ((offset & 1) * 8);
-}
-
-
-WRITE16_MEMBER( ide_controller_device::ide_controller16_pcmcia_w )
-{
- int size;
-
- offset *= 2;
- size = convert_to_offset_and_size16(&offset, mem_mask);
- data = data >> ((offset & 1) * 8);
-
- if (offset < 0x008)
- ide_controller_write(0, offset & 7, size, data);
- if (offset >= 0x008 && offset < 0x010)
- ide_controller_write(1, offset & 7, size, data);
-}
-
READ32_MEMBER( ide_controller_device::ide_bus_master32_r )
{
int size;
@@ -1496,34 +1493,6 @@ WRITE32_MEMBER( ide_controller_device::ide_bus_master32_w )
}
-
-/*************************************
- *
- * 16-bit IDE handlers
- *
- *************************************/
-
-READ16_MEMBER( ide_controller_device::ide_controller16_r )
-{
- int size;
-
- offset *= 2;
- size = convert_to_offset_and_size16(&offset, mem_mask);
-
- return ide_controller_r(offset, size) << ((offset & 1) * 8);
-}
-
-
-WRITE16_MEMBER( ide_controller_device::ide_controller16_w )
-{
- int size;
-
- offset *= 2;
- size = convert_to_offset_and_size16(&offset, mem_mask);
-
- ide_controller_w(offset, size, data >> ((offset & 1) * 8));
-}
-
SLOT_INTERFACE_START(ide_devices)
SLOT_INTERFACE("hdd", IDE_HARDDISK)
SLOT_INTERFACE_END