From 62f3a522f6bfe33de9fd2b82af853ee4eb4beceb Mon Sep 17 00:00:00 2001 From: smf- Date: Sat, 24 Aug 2013 20:02:23 +0000 Subject: [PATCH] Replaced ISA16_IDE_CD with ATAPI_CDROM, replaced ISA16_IDE & ISA16_IDE_CD in southbridge_device with two BUS_MASTER_IDE_CONTROLLERs. [smf] --- .gitattributes | 8 +- src/emu/machine/ataflash.c | 13 +- src/emu/machine/ataflash.h | 2 +- src/emu/machine/atahle.c | 754 +++++++++++++++++++++++ src/emu/machine/atahle.h | 186 ++++++ src/emu/machine/ataintf.c | 4 + src/emu/machine/atapicdr.c | 71 +++ src/emu/machine/atapicdr.h | 34 ++ src/emu/machine/atapihle.c | 198 ++++++ src/emu/machine/atapihle.h | 52 ++ src/emu/machine/idehd.c | 1026 +++++--------------------------- src/emu/machine/idehd.h | 150 ++--- src/emu/machine/machine.mak | 9 +- src/mess/drivers/at.c | 16 +- src/mess/drivers/ct486.c | 7 +- src/mess/machine/isa_cards.c | 1 - src/mess/machine/isa_cards.h | 1 - src/mess/machine/isa_ide_cd.c | 484 --------------- src/mess/machine/isa_ide_cd.h | 92 --- src/mess/machine/southbridge.c | 28 +- src/mess/machine/southbridge.h | 3 +- src/mess/mess.mak | 1 - 22 files changed, 1534 insertions(+), 1606 deletions(-) create mode 100644 src/emu/machine/atahle.c create mode 100644 src/emu/machine/atahle.h create mode 100644 src/emu/machine/atapicdr.c create mode 100644 src/emu/machine/atapicdr.h create mode 100644 src/emu/machine/atapihle.c create mode 100644 src/emu/machine/atapihle.h delete mode 100644 src/mess/machine/isa_ide_cd.c delete mode 100644 src/mess/machine/isa_ide_cd.h diff --git a/.gitattributes b/.gitattributes index 5bbf079f240..155e755b475 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1214,8 +1214,14 @@ src/emu/machine/atadev.c svneol=native#text/plain src/emu/machine/atadev.h svneol=native#text/plain src/emu/machine/ataflash.c svneol=native#text/plain src/emu/machine/ataflash.h svneol=native#text/plain +src/emu/machine/atahle.c svneol=native#text/plain +src/emu/machine/atahle.h svneol=native#text/plain src/emu/machine/ataintf.c svneol=native#text/plain src/emu/machine/ataintf.h svneol=native#text/plain +src/emu/machine/atapicdr.c svneol=native#text/plain +src/emu/machine/atapicdr.h svneol=native#text/plain +src/emu/machine/atapihle.c svneol=native#text/plain +src/emu/machine/atapihle.h svneol=native#text/plain src/emu/machine/ay31015.c svneol=native#text/plain src/emu/machine/ay31015.h svneol=native#text/plain src/emu/machine/bankdev.c svneol=native#text/plain @@ -7530,8 +7536,6 @@ src/mess/machine/isa_ide.c svneol=native#text/plain src/mess/machine/isa_ide.h svneol=native#text/plain src/mess/machine/isa_ide8.c svneol=native#text/plain src/mess/machine/isa_ide8.h svneol=native#text/plain -src/mess/machine/isa_ide_cd.c svneol=native#text/plain -src/mess/machine/isa_ide_cd.h svneol=native#text/plain src/mess/machine/isa_mpu401.c svneol=native#text/plain src/mess/machine/isa_mpu401.h svneol=native#text/plain src/mess/machine/isa_sblaster.c svneol=native#text/plain diff --git a/src/emu/machine/ataflash.c b/src/emu/machine/ataflash.c index 0170f07fe41..9efd4e29af3 100644 --- a/src/emu/machine/ataflash.c +++ b/src/emu/machine/ataflash.c @@ -120,7 +120,7 @@ bool ata_flash_pccard_device::is_ready() return !m_gnetreadlock; } -bool ata_flash_pccard_device::process_command() +void ata_flash_pccard_device::process_command() { switch (m_command) { @@ -131,7 +131,7 @@ bool ata_flash_pccard_device::process_command() m_status |= IDE_STATUS_DRDY; set_irq(ASSERT_LINE); - return true; + break; case IDE_COMMAND_TAITO_GNET_UNLOCK_2: //LOGPRINT(("IDE GNET Unlock 2\n")); @@ -140,7 +140,7 @@ bool ata_flash_pccard_device::process_command() m_status |= IDE_STATUS_DRQ; set_irq(ASSERT_LINE); - return true; + break; case IDE_COMMAND_TAITO_GNET_UNLOCK_3: //LOGPRINT(("IDE GNET Unlock 3\n")); @@ -156,7 +156,7 @@ bool ata_flash_pccard_device::process_command() } set_irq(ASSERT_LINE); - return true; + break; default: if (m_gnetreadlock) @@ -164,10 +164,11 @@ bool ata_flash_pccard_device::process_command() m_status |= IDE_STATUS_ERR; m_error = IDE_ERROR_NONE; m_status &= ~IDE_STATUS_DRDY; - return true; + break; } - return ide_hdd_device::process_command(); + ide_hdd_device::process_command(); + break; } } diff --git a/src/emu/machine/ataflash.h b/src/emu/machine/ataflash.h index 2d6b032cde9..9980c31af9c 100644 --- a/src/emu/machine/ataflash.h +++ b/src/emu/machine/ataflash.h @@ -24,7 +24,7 @@ protected: virtual void device_start(); virtual void device_reset(); - virtual bool process_command(); + virtual void process_command(); virtual void process_buffer(); virtual bool is_ready(); diff --git a/src/emu/machine/atahle.c b/src/emu/machine/atahle.c new file mode 100644 index 00000000000..f88dcafb4f8 --- /dev/null +++ b/src/emu/machine/atahle.c @@ -0,0 +1,754 @@ +#include "atahle.h" + +#define VERBOSE 0 +#define PRINTF_IDE_COMMANDS 0 + +#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#define LOGPRINT(x) do { if (VERBOSE) logerror x; if (PRINTF_IDE_COMMANDS) mame_printf_debug x; } while (0) + +enum +{ + IDE_CS0_DATA_RW = 0, + IDE_CS0_ERROR_R = 1, + IDE_CS0_FEATURE_W = 1, + IDE_CS0_SECTOR_COUNT_RW = 2, + IDE_CS0_SECTOR_NUMBER_RW = 3, + IDE_CS0_CYLINDER_LOW_RW = 4, + IDE_CS0_CYLINDER_HIGH_RW = 5, + IDE_CS0_DEVICE_HEAD_RW = 6, + IDE_CS0_STATUS_R = 7, + IDE_CS0_COMMAND_W = 7 +}; + +enum +{ + IDE_CS1_ALTERNATE_STATUS_R = 6, + IDE_CS1_DEVICE_CONTROL_W = 6 +}; + +enum +{ + IDE_DEVICE_CONTROL_NIEN = 0x02, + IDE_DEVICE_CONTROL_SRST = 0x04 +}; + +#define DETECT_DEVICE1_TIME (attotime::from_msec(2)) +#define DEVICE1_PDIAG_TIME (attotime::from_msec(2)) +#define DIAGNOSTIC_TIME (attotime::from_msec(2)) + +ata_hle_device::ata_hle_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source), + ata_device_interface(mconfig, *this), + device_slot_card_interface(mconfig, *this), + m_buffer_offset(0), + m_buffer_size(0), + m_error(0), + m_feature(0), + m_sector_count(0), + m_sector_number(0), + m_cylinder_low(0), + m_cylinder_high(0), + m_device_head(0), + m_status(0), + m_command(0), + m_device_control(0), + m_csel(0), + m_daspin(0), + m_daspout(0), + m_dmack(0), + m_dmarq(0), + m_irq(0), + m_pdiagin(0), + m_pdiagout(0), + m_single_device(0), + m_resetting(0) +{ +} + +void ata_hle_device::device_start() +{ + MINIMUM_COMMAND_TIME = attotime::from_usec(10); + + m_irq_handler.resolve_safe(); + m_dmarq_handler.resolve_safe(); + m_dasp_handler.resolve_safe(); + m_pdiag_handler.resolve_safe(); + + m_buffer = auto_alloc_array(machine(), UINT8, sector_length()); + save_pointer(NAME(m_buffer), sector_length()); + save_item(NAME(m_buffer_offset)); + save_item(NAME(m_error)); + 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_single_device)); + save_item(NAME(m_resetting)); + + save_item(NAME(m_csel)); + save_item(NAME(m_daspin)); + save_item(NAME(m_daspout)); + save_item(NAME(m_dmack)); + save_item(NAME(m_dmarq)); + save_item(NAME(m_irq)); + save_item(NAME(m_pdiagin)); + save_item(NAME(m_pdiagout)); + + m_busy_timer = timer_alloc(TID_BUSY); +} + +void ata_hle_device::device_reset() +{ + /* reset the drive state */ + set_dasp(CLEAR_LINE); + set_dmarq(CLEAR_LINE); + set_irq(CLEAR_LINE); + set_pdiag(CLEAR_LINE); + + m_status = 0; + m_device_control = 0; + m_resetting = true; + + if (m_csel == 0) + { + start_busy(DETECT_DEVICE1_TIME, PARAM_DETECT_DEVICE1); + } + else + { + set_dasp(ASSERT_LINE); + soft_reset(); + } +} + +void ata_hle_device::soft_reset() +{ + m_buffer_offset = 0; + m_buffer_size = 0; + m_status = 0; + + if (is_ready()) + { + m_status |= IDE_STATUS_DRDY; + } + + start_busy(DIAGNOSTIC_TIME, PARAM_DIAGNOSTIC); +} + +void ata_hle_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch(id) + { + case TID_BUSY: + m_status &= ~IDE_STATUS_BSY; + + finished_busy(param); + break; + } +} + +void ata_hle_device::finished_busy(int param) +{ + switch (param) + { + case PARAM_DETECT_DEVICE1: + m_single_device = (m_daspin == CLEAR_LINE); + soft_reset(); + break; + + case PARAM_DIAGNOSTIC: + start_diagnostic(); + break; + + case PARAM_WAIT_FOR_PDIAG: + m_error |= IDE_ERROR_DIAGNOSTIC_DEVICE1_FAILED; + finished_diagnostic(); + break; + + case PARAM_COMMAND: + finished_command(); + break; + } +} + +void ata_hle_device::process_command() +{ + switch (m_command) + { + case IDE_COMMAND_DIAGNOSTIC: + start_busy(DIAGNOSTIC_TIME, PARAM_COMMAND); + break; + + default: + LOGPRINT(("IDE unknown command (%02X)\n", m_command)); + m_status |= IDE_STATUS_ERR; + m_error = IDE_ERROR_ABRT; + set_irq(ASSERT_LINE); + //debugger_break(device->machine()); + break; + } +} + +void ata_hle_device::finished_command() +{ + switch (m_command) + { + case IDE_COMMAND_DIAGNOSTIC: + start_diagnostic(); + + if (m_csel == 0) + set_irq(ASSERT_LINE); + break; + + default: + logerror( "finished_command() unhandled command %02x\n", m_command ); + break; + } +} + +UINT16 ata_hle_device::read_data(UINT16 mem_mask) +{ + /* fetch the correct amount of data */ + UINT16 result = m_buffer[m_buffer_offset++]; + if (ACCESSING_BITS_8_15) + result |= m_buffer[m_buffer_offset++] << 8; + + /* if we're at the end of the buffer, handle it */ + if (m_buffer_offset >= m_buffer_size) + { + LOG(("%s:IDE completed PIO read\n", machine().describe_context())); + read_buffer_empty(); + } + + return result; +} + +void ata_hle_device::write_data(UINT16 data, UINT16 mem_mask) +{ + /* store the correct amount of data */ + m_buffer[m_buffer_offset++] = data; + if (ACCESSING_BITS_8_15) + m_buffer[m_buffer_offset++] = data >> 8; + + /* if we're at the end of the buffer, handle it */ + if (m_buffer_offset >= m_buffer_size) + { + LOG(("%s:IDE completed PIO write\n", machine().describe_context())); + write_buffer_full(); + } +} + +void ata_hle_device::update_irq() +{ + if (device_selected() && (m_device_control & IDE_DEVICE_CONTROL_NIEN) == 0) + m_irq_handler(m_irq); + else + m_irq_handler(CLEAR_LINE); +} + +void ata_hle_device::set_irq(int state) +{ + if (m_irq != state) + { + m_irq = state; + + update_irq(); + } +} + +void ata_hle_device::set_dmarq(int state) +{ + if (m_dmarq != state) + { + m_dmarq = state; + + m_dmarq_handler(state); + } +} + +void ata_hle_device::set_dasp(int state) +{ + if (m_daspout != state) + { + m_daspout = state; + + m_dasp_handler(state); + } +} + +void ata_hle_device::set_pdiag(int state) +{ + if (m_pdiagout != state) + { + m_pdiagout = state; + + m_pdiag_handler(state); + } +} + +void ata_hle_device::start_busy(attotime time, int param) +{ + m_status |= IDE_STATUS_BSY; + m_busy_timer->adjust(time, param); +} + +void ata_hle_device::stop_busy() +{ + m_status &= ~IDE_STATUS_BSY; + m_busy_timer->adjust(attotime::never); +} + +void ata_hle_device::read_buffer_empty() +{ + m_buffer_offset = 0; + + m_status &= ~IDE_STATUS_DRQ; + set_dmarq(CLEAR_LINE); + + fill_buffer(); +} + +void ata_hle_device::write_buffer_full() +{ + m_buffer_offset = 0; + + m_status &= ~IDE_STATUS_DRQ; + set_dmarq(CLEAR_LINE); + + process_buffer(); +} + +void ata_hle_device::start_diagnostic() +{ + m_error = IDE_ERROR_DIAGNOSTIC_FAILED; + + perform_diagnostic(); + + if (m_csel == 1 && m_error == IDE_ERROR_DIAGNOSTIC_PASSED) + set_pdiag(ASSERT_LINE); + + if (m_csel == 0 && !m_single_device && m_pdiagin == CLEAR_LINE) + start_busy(DEVICE1_PDIAG_TIME, PARAM_WAIT_FOR_PDIAG); + else + finished_diagnostic(); +} + +void ata_hle_device::finished_diagnostic() +{ + m_resetting = false; + + signature(); +} + + +WRITE_LINE_MEMBER( ata_hle_device::write_csel ) +{ + m_csel = state; +} + +WRITE_LINE_MEMBER( ata_hle_device::write_dasp ) +{ + m_daspin = state; +} + +WRITE_LINE_MEMBER( ata_hle_device::write_dmack ) +{ + m_dmack = state; +} + +WRITE_LINE_MEMBER( ata_hle_device::write_pdiag ) +{ + m_pdiagin = state; + + if (m_pdiagin == ASSERT_LINE && m_busy_timer->param() == PARAM_WAIT_FOR_PDIAG) + { + stop_busy(); + finished_diagnostic(); + } +} + +UINT16 ata_hle_device::read_dma() +{ + UINT16 result = 0xffff; + + if (device_selected()) + { + if (!m_dmack) + { + logerror( "%s: %s dev %d read_dma ignored (!DMACK)\n", machine().describe_context(), tag(), dev() ); + } + else if (!m_dmarq) + { + logerror( "%s: %s dev %d read_dma ignored (!DMARQ)\n", machine().describe_context(), tag(), dev() ); + } + else if (m_status & IDE_STATUS_BSY) + { + logerror( "%s: %s dev %d read_dma ignored (BSY)\n", machine().describe_context(), tag(), dev() ); + } + else if (!(m_status & IDE_STATUS_DRQ)) + { + logerror( "%s: %s dev %d read_dma ignored (!DRQ)\n", machine().describe_context(), tag(), dev() ); + } + else + { + result = read_data(0xffff); + } + } + + return result; +} + +READ16_MEMBER( ata_hle_device::read_cs0 ) +{ + /* logit */ +// 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)); + + UINT16 result = 0xffff; + + if (device_selected() || m_single_device) + { + if (m_dmack) + { + logerror( "%s: %s dev %d read_cs0 %04x %04x ignored (DMACK)\n", machine().describe_context(), tag(), dev(), offset, mem_mask ); + } + else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_STATUS_R) + { + // ATA5 spec says status reads should also go through here, but this breaks Primal Rage 2. + // Real hardware might work due to read ahead in the vt83c461. + if (device_selected()) + { + switch (offset) + { + case IDE_CS0_DATA_RW: + logerror( "%s: %s dev %d read_cs0 %04x %04x ignored (BSY)\n", machine().describe_context(), tag(), dev(), offset, mem_mask ); + break; + + default: + result = calculate_status(); + break; + } + } + else + { + result = 0; + } + } + else + { + switch (offset) + { + /* read data if there's data to be read */ + case IDE_CS0_DATA_RW: + if (device_selected()) + { + if (!(m_status & IDE_STATUS_DRQ)) + { + logerror( "%s: %s dev %d read_cs0 ignored (!DRQ)\n", machine().describe_context(), tag(), dev() ); + } + else + { + result = read_data(mem_mask); + } + } + else + { + result = 0; + } + break; + + /* return the current error */ + case IDE_CS0_ERROR_R: + result = m_error; + break; + + /* return the current sector count */ + case IDE_CS0_SECTOR_COUNT_RW: + result = m_sector_count; + break; + + /* return the current sector */ + case IDE_CS0_SECTOR_NUMBER_RW: + result = m_sector_number; + break; + + /* return the current cylinder LSB */ + case IDE_CS0_CYLINDER_LOW_RW: + result = m_cylinder_low; + break; + + /* return the current cylinder MSB */ + case IDE_CS0_CYLINDER_HIGH_RW: + result = m_cylinder_high; + break; + + /* return the current head */ + case IDE_CS0_DEVICE_HEAD_RW: + result = m_device_head; + break; + + /* return the current status and clear any pending interrupts */ + case IDE_CS0_STATUS_R: + if (device_selected()) + { + result = calculate_status(); + + if (!(m_status & IDE_STATUS_DRDY) && is_ready()) + m_status |= IDE_STATUS_DRDY; + + set_irq(CLEAR_LINE); + } + else + { + result = 0; + } + break; + + /* log anything else */ + default: + logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); + break; + } + } + } + + /* return the result */ + return result; +} + +READ16_MEMBER( ata_hle_device::read_cs1 ) +{ + /* logit */ +// if (offset != IDE_CS1_ALTERNATE_STATUS_R) + LOG(("%s:IDE cs1 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask)); + + UINT16 result = 0xffff; + + if (device_selected() || m_single_device) + { + if (m_dmack) + { + logerror( "%s: %s dev %d read_cs1 %04x %04x ignored (DMACK)\n", machine().describe_context(), tag(), dev(), offset, mem_mask ); + } + else + { + switch (offset) + { + case IDE_CS1_ALTERNATE_STATUS_R: + if (device_selected()) + { + result = calculate_status(); + } + else + { + result = 0; + } + break; + + /* log anything else */ + default: + logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); + break; + } + } + } + + /* return the result */ + return result; +} + +void ata_hle_device::write_dma( UINT16 data ) +{ + if (device_selected()) + { + if (!m_dmack) + { + logerror( "%s: %s dev %d write_dma %04x ignored (!DMACK)\n", machine().describe_context(), tag(), dev(), data ); + } + else if (!m_dmarq) + { + logerror( "%s: %s dev %d write_dma %04x ignored (!DMARQ)\n", machine().describe_context(), tag(), dev(), data ); + } + else if (m_status & IDE_STATUS_BSY) + { + logerror( "%s: %s dev %d write_dma %04x ignored (BSY)\n", machine().describe_context(), tag(), dev(), data ); + } + else if (!(m_status & IDE_STATUS_DRQ)) + { + logerror( "%s: %s dev %d write_dma %04x ignored (!DRQ)\n", machine().describe_context(), tag(), dev(), data ); + } + else + { + write_data(data, 0xffff); + } + } +} + +WRITE16_MEMBER( ata_hle_device::write_cs0 ) +{ + /* 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)); + // fprintf(stderr, "ide write %03x %02x mem_mask=%d\n", offset, data, size); + + if (m_dmack) + { + logerror( "%s: %s dev %d write_cs0 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask ); + } + else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_COMMAND_W) + { + logerror( "%s: %s dev %d write_cs0 %04x %04x %04x ignored (BSY) command %02x\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask, m_command ); + } + else if ((m_status & IDE_STATUS_DRQ) && offset != IDE_CS0_DATA_RW && offset != IDE_CS0_COMMAND_W) + { + logerror( "%s: %s dev %d write_cs0 %04x %04x %04x ignored (DRQ) command %02x\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask, m_command ); + } + else + { + UINT8 old; + + switch (offset) + { + /* write data */ + case IDE_CS0_DATA_RW: + if (device_selected()) + { + if (!(m_status & IDE_STATUS_DRQ)) + { + logerror( "%s: %s dev %d write_cs0 %04x %04x %04x ignored (!DRQ)\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask ); + } + else + { + write_data(data, mem_mask); + } + } + break; + + case IDE_CS0_FEATURE_W: + m_feature = data; + break; + + /* sector count */ + case IDE_CS0_SECTOR_COUNT_RW: + m_sector_count = data ? data : 256; + break; + + /* current sector */ + case IDE_CS0_SECTOR_NUMBER_RW: + m_sector_number = data; + break; + + /* current cylinder LSB */ + case IDE_CS0_CYLINDER_LOW_RW: + m_cylinder_low = data; + break; + + /* current cylinder MSB */ + case IDE_CS0_CYLINDER_HIGH_RW: + m_cylinder_high = data; + break; + + /* current head */ + case IDE_CS0_DEVICE_HEAD_RW: + old = m_device_head; + m_device_head = data; + + if ((m_device_head ^ old) & IDE_DEVICE_HEAD_DRV) + update_irq(); + break; + + /* command */ + case IDE_CS0_COMMAND_W: + // Packet devices can accept DEVICE RESET when BSY or DRQ is set. + if (m_status & IDE_STATUS_BSY) + { + logerror( "%s: %s dev %d write_cs0 %04x %04x %04x ignored (BSY) command %02x\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask, m_command ); + } + else if (m_status & IDE_STATUS_DRQ) + { + logerror( "%s: %s dev %d write_cs0 %04x %04x %04x ignored (DRQ) command %02x\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask, m_command ); + } + else if (device_selected() || m_command == IDE_COMMAND_DIAGNOSTIC) + { + m_command = data; + + /* implicitly clear interrupts & dmarq here */ + set_irq(CLEAR_LINE); + set_dmarq(CLEAR_LINE); + + m_buffer_offset = 0; + + set_dasp(CLEAR_LINE); + m_status &= ~IDE_STATUS_DRQ; + m_status &= ~IDE_STATUS_ERR; + + process_command(); + } + break; + + default: + logerror("%s:unknown IDE cs0 write at %03X = %04x, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask); + break; + } + } +} + +WRITE16_MEMBER( ata_hle_device::write_cs1 ) +{ + /* logit */ + LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); + + if (m_dmack) + { + logerror( "%s: %s dev %d write_cs1 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask ); + } + else + { + UINT8 old; + + switch (offset) + { + /* adapter control */ + case IDE_CS1_DEVICE_CONTROL_W: + old = m_device_control; + m_device_control = data; + + if ((m_device_control ^ old) & IDE_DEVICE_CONTROL_NIEN) + update_irq(); + + if ((m_device_control ^ old) & IDE_DEVICE_CONTROL_SRST) + { + if (m_device_control & IDE_DEVICE_CONTROL_SRST) + { + if (m_resetting) + { + logerror( "%s: %s dev %d write_cs1 %04x %04x %04x ignored (RESET)\n", machine().describe_context(), tag(), dev(), offset, data, mem_mask ); + } + else + { + set_dasp(CLEAR_LINE); + set_dmarq(CLEAR_LINE); + set_irq(CLEAR_LINE); + set_pdiag(CLEAR_LINE); + + start_busy(attotime::never, PARAM_RESET); + } + } + else if (m_busy_timer->param() == PARAM_RESET) + { + soft_reset(); + } + } + break; + + default: + logerror("%s:unknown IDE cs1 write at %03X = %04x, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask); + break; + } + } +} diff --git a/src/emu/machine/atahle.h b/src/emu/machine/atahle.h new file mode 100644 index 00000000000..f13e4979571 --- /dev/null +++ b/src/emu/machine/atahle.h @@ -0,0 +1,186 @@ +/*************************************************************************** + + atahle.h + + ATA Device HLE + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#pragma once + +#ifndef __ATAHLE_H__ +#define __ATAHLE_H__ + +#include "atadev.h" + +class ata_hle_device : public device_t, + public ata_device_interface, + public device_slot_card_interface +{ +public: + ata_hle_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source); + + virtual UINT16 read_dma(); + virtual DECLARE_READ16_MEMBER(read_cs0); + virtual DECLARE_READ16_MEMBER(read_cs1); + + virtual void write_dma(UINT16 data); + virtual DECLARE_WRITE16_MEMBER(write_cs0); + virtual DECLARE_WRITE16_MEMBER(write_cs1); + virtual DECLARE_WRITE_LINE_MEMBER(write_csel); + virtual DECLARE_WRITE_LINE_MEMBER(write_dasp); + virtual DECLARE_WRITE_LINE_MEMBER(write_dmack); + virtual DECLARE_WRITE_LINE_MEMBER(write_pdiag); + +protected: + virtual void device_start(); + virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + + void set_irq(int state); + void set_dmarq(int state); + void set_dasp(int state); + void set_pdiag(int state); + + void start_busy(attotime time, int param); + void stop_busy(); + + int dev() { return (m_device_head & IDE_DEVICE_HEAD_DRV) >> 4; } + bool device_selected() { return m_csel == dev(); } + + virtual UINT8 calculate_status() { return m_status; } + virtual void soft_reset(); + virtual void process_command(); + virtual void finished_command(); + virtual int sector_length() = 0; + virtual void process_buffer() = 0; + virtual void fill_buffer() = 0; + virtual bool is_ready() = 0; + virtual void perform_diagnostic() = 0; + virtual void signature() = 0; + virtual UINT16 read_data(UINT16 mem_mask); + virtual void write_data(UINT16 data, UINT16 mem_mask); + + /// TODO: not sure this should be protected. + void read_buffer_empty(); + + enum + { + IDE_STATUS_ERR = 0x01, // Error + IDE_STATUS_IDX = 0x02, // Index + IDE_STATUS_CORR = 0x04, // Corrected Data + IDE_STATUS_DRQ = 0x08, // Data Request + IDE_STATUS_DSC = 0x10, // ATA Drive Seek Complete + IDE_STATUS_SERV = 0x10, // ATAPI Service + IDE_STATUS_DWF = 0x20, // ATA Drive Write Fault + IDE_STATUS_DMRD = 0x20, // ATAPI DMA Ready + IDE_STATUS_DRDY = 0x40, // Drive Ready + IDE_STATUS_BSY = 0x80 // Busy + }; + + enum + { + IDE_ERROR_NONE = 0x00, + IDE_ERROR_DIAGNOSTIC_OK = 0x01, + IDE_ERROR_TRACK0_NOT_FOUND = 0x02, + IDE_ERROR_ABRT = 0x04, + IDE_ERROR_BAD_LOCATION = 0x10, + IDE_ERROR_BAD_SECTOR = 0x80, + IDE_ERROR_DIAGNOSTIC_FAILED = 0x00, + IDE_ERROR_DIAGNOSTIC_PASSED = 0x01, + IDE_ERROR_DIAGNOSTIC_DEVICE1_FAILED = 0x80 + }; + + enum + { + IDE_COMMAND_NOP = 0x00, + IDE_COMMAND_DEVICE_RESET = 0x08, + IDE_COMMAND_RECALIBRATE = 0x10, + IDE_COMMAND_READ_SECTORS = 0x20, + IDE_COMMAND_READ_SECTORS_NORETRY = 0x21, + IDE_COMMAND_WRITE_SECTORS = 0x30, + IDE_COMMAND_WRITE_SECTORS_NORETRY = 0x31, + IDE_COMMAND_VERIFY_SECTORS = 0x40, + IDE_COMMAND_VERIFY_SECTORS_NORETRY = 0x41, + IDE_COMMAND_SEEK = 0x70, + IDE_COMMAND_DIAGNOSTIC = 0x90, + IDE_COMMAND_SET_CONFIG = 0x91, + IDE_COMMAND_PACKET = 0xa0, + IDE_COMMAND_IDENTIFY_PACKET_DEVICE = 0xa1, + IDE_COMMAND_READ_MULTIPLE = 0xc4, + IDE_COMMAND_WRITE_MULTIPLE = 0xc5, + IDE_COMMAND_SET_BLOCK_COUNT = 0xc6, + IDE_COMMAND_READ_DMA = 0xc8, + IDE_COMMAND_WRITE_DMA = 0xca, + IDE_COMMAND_IDLE_IMMEDIATE = 0xe1, + IDE_COMMAND_IDLE = 0xe3, + IDE_COMMAND_IDENTIFY_DEVICE = 0xec, + IDE_COMMAND_SET_FEATURES = 0xef, + IDE_COMMAND_SECURITY_UNLOCK = 0xf2, + IDE_COMMAND_SET_MAX = 0xf9 + }; + + enum + { + IDE_DEVICE_HEAD_HS = 0x0f, + IDE_DEVICE_HEAD_DRV = 0x10, + IDE_DEVICE_HEAD_L = 0x40, + IDE_DEVICE_HEAD_OBSOLETE = 0x80 | 0x20 + }; + + enum + { + TID_BUSY + }; + + enum + { + PARAM_RESET, + PARAM_DETECT_DEVICE1, + PARAM_DIAGNOSTIC, + PARAM_WAIT_FOR_PDIAG, + PARAM_COMMAND + }; + + attotime MINIMUM_COMMAND_TIME; + + UINT8 *m_buffer; + UINT16 m_buffer_offset; + UINT16 m_buffer_size; + 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; + +private: + void update_irq(); + void write_buffer_full(); + void start_diagnostic(); + void finished_diagnostic(); + void finished_busy(int param); + + int m_csel; + int m_daspin; + int m_daspout; + int m_dmack; + int m_dmarq; + int m_irq; + int m_pdiagin; + int m_pdiagout; + + bool m_single_device; + bool m_resetting; + + emu_timer *m_busy_timer; +}; + +#endif diff --git a/src/emu/machine/ataintf.c b/src/emu/machine/ataintf.c index 027a8ded646..6082cf4d1ab 100644 --- a/src/emu/machine/ataintf.c +++ b/src/emu/machine/ataintf.c @@ -13,6 +13,7 @@ #include "ataintf.h" #include "debugger.h" #include "idehd.h" +#include "atapicdr.h" void ata_interface_device::set_irq(int state) { @@ -140,6 +141,8 @@ READ16_MEMBER( ata_interface_device::read_cs0 ) if (m_slot[i]->dev() != NULL) result &= m_slot[i]->dev()->read_cs0(space, offset, mem_mask); +// { static int last_status = -1; if (offset == 7 ) { if( result == last_status ) return last_status; last_status = result; } else last_status = -1; } + // printf( "read cs0 %04x %04x %04x\n", offset, result, mem_mask ); return result; @@ -202,6 +205,7 @@ WRITE_LINE_MEMBER( ata_interface_device::write_dmack ) SLOT_INTERFACE_START(ata_devices) SLOT_INTERFACE("hdd", IDE_HARDDISK) + SLOT_INTERFACE("cdrom", ATAPI_CDROM) SLOT_INTERFACE_END ata_interface_device::ata_interface_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : diff --git a/src/emu/machine/atapicdr.c b/src/emu/machine/atapicdr.c new file mode 100644 index 00000000000..e1b42f5dacd --- /dev/null +++ b/src/emu/machine/atapicdr.c @@ -0,0 +1,71 @@ +#include "atapicdr.h" +#include "scsicd.h" + +// device type definition +const device_type ATAPI_CDROM = &device_creator; + +atapi_cdrom_device::atapi_cdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : atapi_hle_device(mconfig, ATAPI_CDROM, "ATAPI CDROM", tag, owner, clock, "cdrom", __FILE__) +{ +} + +static MACHINE_CONFIG_FRAGMENT( atapicdr ) + MCFG_DEVICE_ADD("device", SCSICD, 0) +MACHINE_CONFIG_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +machine_config_constructor atapi_cdrom_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( atapicdr ); +} + +void atapi_cdrom_device::perform_diagnostic() +{ + m_error = IDE_ERROR_DIAGNOSTIC_PASSED; +} + +void atapi_cdrom_device::identify_packet_device() +{ + m_buffer_size = 512; + + memset(m_buffer, 0, m_buffer_size); + + m_buffer[ 0 ^ 1 ] = 0x85; // ATAPI device, cmd set 5 compliant, DRQ within 3 ms of PACKET command + m_buffer[ 1 ^ 1 ] = 0x80; // ATAPI device, removable media + + memset( &m_buffer[ 46 ], ' ', 8 ); + m_buffer[ 46 ^ 1 ] = '1'; + m_buffer[ 47 ^ 1 ] = '.'; + m_buffer[ 48 ^ 1 ] = '0'; + + memset( &m_buffer[ 54 ], ' ', 40 ); + m_buffer[ 54 ^ 1 ] = 'M'; + m_buffer[ 55 ^ 1 ] = 'A'; + m_buffer[ 56 ^ 1 ] = 'M'; + m_buffer[ 57 ^ 1 ] = 'E'; + m_buffer[ 58 ^ 1 ] = ' '; + m_buffer[ 59 ^ 1 ] = 'C'; + m_buffer[ 60 ^ 1 ] = 'o'; + m_buffer[ 61 ^ 1 ] = 'm'; + m_buffer[ 62 ^ 1 ] = 'p'; + m_buffer[ 63 ^ 1 ] = 'r'; + m_buffer[ 64 ^ 1 ] = 'e'; + m_buffer[ 65 ^ 1 ] = 's'; + m_buffer[ 66 ^ 1 ] = 's'; + m_buffer[ 67 ^ 1 ] = 'e'; + m_buffer[ 68 ^ 1 ] = 'd'; + m_buffer[ 69 ^ 1 ] = ' '; + m_buffer[ 70 ^ 1 ] = 'C'; + m_buffer[ 71 ^ 1 ] = 'D'; + m_buffer[ 72 ^ 1 ] = '-'; + m_buffer[ 73 ^ 1 ] = 'R'; + m_buffer[ 74 ^ 1 ] = 'O'; + m_buffer[ 75 ^ 1 ] = 'M'; + + m_buffer[ 98 ^ 1 ] = 0x06; // Word 49=Capabilities, IORDY may be disabled (bit_10), LBA Supported mandatory (bit_9) + m_buffer[ 99 ^ 1 ] = 0x00; +} diff --git a/src/emu/machine/atapicdr.h b/src/emu/machine/atapicdr.h new file mode 100644 index 00000000000..fa913ccd9e0 --- /dev/null +++ b/src/emu/machine/atapicdr.h @@ -0,0 +1,34 @@ +/*************************************************************************** + + atapicdr.h + + ATAPI CDROM + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#pragma once + +#ifndef __ATAPICDR_H__ +#define __ATAPICDR_H__ + +#include "atapihle.h" + +class atapi_cdrom_device : public atapi_hle_device +{ +public: + atapi_cdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + virtual machine_config_constructor device_mconfig_additions() const; + + virtual void perform_diagnostic(); + virtual void identify_packet_device(); +}; + +// device type definition +extern const device_type ATAPI_CDROM; + +#endif diff --git a/src/emu/machine/atapihle.c b/src/emu/machine/atapihle.c new file mode 100644 index 00000000000..62f7ccf703e --- /dev/null +++ b/src/emu/machine/atapihle.c @@ -0,0 +1,198 @@ +#include "atapihle.h" + +atapi_hle_device::atapi_hle_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source) + : ata_hle_device(mconfig, type, name, tag, owner, clock, shortname, source), + m_packet(0), + m_data_size(0), + m_scsidev_device(*this, "device") +{ +} + +void atapi_hle_device::process_buffer() +{ + if (m_packet) + { + int phase; + + // printf( "atapi command %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + // m_buffer[0],m_buffer[1],m_buffer[2],m_buffer[3], + // m_buffer[4],m_buffer[5],m_buffer[6],m_buffer[7], + // m_buffer[8],m_buffer[9],m_buffer[10],m_buffer[11]); + + m_scsidev_device->SetCommand( m_buffer, m_buffer_size ); + m_scsidev_device->ExecCommand( &m_data_size ); + m_scsidev_device->GetPhase( &phase ); + + m_buffer_size = (m_cylinder_high << 8) | m_cylinder_low; + if (m_buffer_size == 0xffff) + m_buffer_size = 0xfffe; + + // printf("atapi result %08x %08x\n", m_data_size, m_buffer_size); + + if (m_buffer_size > ATAPI_BUFFER_LENGTH || m_buffer_size == 0) + m_buffer_size = ATAPI_BUFFER_LENGTH; + + // TODO: dma flag + switch (phase) + { + case SCSI_PHASE_DATAOUT: + if (m_buffer_size > m_data_size) + { + m_buffer_size = m_data_size; + } + + m_cylinder_low = m_buffer_size & 0xff; + m_cylinder_high = m_buffer_size >> 8; + + if (m_buffer_size > 0) + { + m_status |= IDE_STATUS_DRQ; + m_sector_count = 0; + } + else + { + m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD; + } + break; + + case SCSI_PHASE_DATAIN: + /// TODO: delay data + fill_buffer(); + break; + + default: + m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD; + break; + } + + set_irq(ASSERT_LINE); + + m_packet = 0; + } + else + { + switch (m_command) + { + case IDE_COMMAND_PACKET: + m_scsidev_device->WriteData( m_buffer, m_buffer_size ); + m_data_size -= m_buffer_size; + + if (m_buffer_size > m_data_size) + { + m_buffer_size = m_data_size; + } + + m_cylinder_low = m_buffer_size & 0xff; + m_cylinder_high = m_buffer_size >> 8; + + if (m_buffer_size > 0) + { + m_status |= IDE_STATUS_DRQ; + m_sector_count = 0; + } + else + { + m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD; + } + + set_irq(ASSERT_LINE); + break; + } + } +} + +void atapi_hle_device::fill_buffer() +{ + switch (m_command) + { + case IDE_COMMAND_PACKET: + if (m_buffer_size > m_data_size) + { + m_buffer_size = m_data_size; + } + + m_cylinder_low = m_buffer_size & 0xff; + m_cylinder_high = m_buffer_size >> 8; + + if (m_buffer_size > 0) + { + m_scsidev_device->ReadData( m_buffer, m_buffer_size ); + m_data_size -= m_buffer_size; + + m_status |= IDE_STATUS_DRQ; + m_sector_count = ATAPI_INTERRUPT_REASON_IO; + } + else + { + m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD; + } + + set_irq(ASSERT_LINE); + break; + + case IDE_COMMAND_IDENTIFY_PACKET_DEVICE: + m_sector_count = ATAPI_INTERRUPT_REASON_IO | ATAPI_INTERRUPT_REASON_CD; + set_irq(ASSERT_LINE); + break; + } +} + +void atapi_hle_device::signature() +{ + // TODO: IDENTIFY DEVICE & READ SECTORS writes signature too. + m_sector_count = 1; + m_sector_number = 1; + m_cylinder_low = 0x14; + m_cylinder_high = 0xeb; + + m_device_head &= IDE_DEVICE_HEAD_DRV; +} + +void atapi_hle_device::process_command() +{ + m_packet = 0; + + switch (m_command) + { + case IDE_COMMAND_DEVICE_RESET: + soft_reset(); + break; + + case IDE_COMMAND_PACKET: + m_packet = 1; + m_buffer_size = 12; + m_status |= IDE_STATUS_DRQ; + m_sector_count = ATAPI_INTERRUPT_REASON_CD; + set_irq(ASSERT_LINE); + break; + + case IDE_COMMAND_IDENTIFY_PACKET_DEVICE: + identify_packet_device(); + + m_status |= IDE_STATUS_DRQ; + set_irq(ASSERT_LINE); + break; + + case IDE_COMMAND_IDENTIFY_DEVICE: + /// TODO: busy + signature(); + m_status |= IDE_STATUS_ERR; + m_error = IDE_ERROR_ABRT; + set_irq(ASSERT_LINE); + break; + + default: + ata_hle_device::process_command(); + break; + } +} + +void atapi_hle_device::finished_command() +{ + switch (m_command) + { + default: + ata_hle_device::finished_command(); + break; + } +} diff --git a/src/emu/machine/atapihle.h b/src/emu/machine/atapihle.h new file mode 100644 index 00000000000..8266db46679 --- /dev/null +++ b/src/emu/machine/atapihle.h @@ -0,0 +1,52 @@ +/*************************************************************************** + + atapihle.h + + ATAPI High Level Emulation + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#pragma once + +#ifndef __ATAPIHLE_H__ +#define __ATAPIHLE_H__ + +#include "atahle.h" +#include "scsihle.h" + +class atapi_hle_device : public ata_hle_device +{ +public: + atapi_hle_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source); + + enum + { + ATAPI_INTERRUPT_REASON_CD = 0x01, // 1 = command, 0 = data + ATAPI_INTERRUPT_REASON_IO = 0x02, // 1 = to host, 0 = to device + ATAPI_INTERRUPT_REASON_REL = 0x04, // 1 = bus release + ATAPI_INTERRUPT_REASON_TAG = 0xf8 // command tag + }; + +protected: + virtual int sector_length() { return ATAPI_BUFFER_LENGTH; } + virtual void process_buffer(); + virtual void fill_buffer(); + virtual bool is_ready() { return false ; } + virtual void signature(); + virtual void process_command(); + virtual void finished_command(); + + virtual void identify_packet_device() = 0; + +private: + int m_packet; + int m_data_size; + required_device m_scsidev_device; + + static const int ATAPI_BUFFER_LENGTH = 0x800; +}; + +#endif diff --git a/src/emu/machine/idehd.c b/src/emu/machine/idehd.c index 616f845fc6a..78cb610a569 100644 --- a/src/emu/machine/idehd.c +++ b/src/emu/machine/idehd.c @@ -8,12 +8,8 @@ #define PRINTF_IDE_COMMANDS 0 #define PRINTF_IDE_PASSWORD 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) - #define LOGPRINT(x) do { if (VERBOSE) logerror x; if (PRINTF_IDE_COMMANDS) mame_printf_debug x; } while (0) -#define MINIMUM_COMMAND_TIME (attotime::from_usec(10)) - #define TIME_PER_SECTOR (attotime::from_usec(100)) #define TIME_PER_ROTATION (attotime::from_hz(5400/60)) #define TIME_MULTIPLE_SECTORS (attotime::from_usec(1)) @@ -21,162 +17,14 @@ #define TIME_SEEK_MULTISECTOR (attotime::from_msec(13)) #define TIME_NO_SEEK_MULTISECTOR (attotime::from_nsec(16300)) -#define DIAGNOSTIC_TIME (attotime::from_msec(2)) -#define DETECT_DEVICE1_TIME (attotime::from_msec(2)) -#define DEVICE1_PDIAG_TIME (attotime::from_msec(2)) - -#define IDE_CS0_DATA_RW 0 -#define IDE_CS0_ERROR_R 1 -#define IDE_CS0_FEATURE_W 1 -#define IDE_CS0_SECTOR_COUNT_RW 2 -#define IDE_CS0_SECTOR_NUMBER_RW 3 -#define IDE_CS0_CYLINDER_LOW_RW 4 -#define IDE_CS0_CYLINDER_HIGH_RW 5 -#define IDE_CS0_DEVICE_HEAD_RW 6 -#define IDE_CS0_STATUS_R 7 -#define IDE_CS0_COMMAND_W 7 - -#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_NORETRY 0x21 -#define IDE_COMMAND_WRITE_SECTORS 0x30 -#define IDE_COMMAND_WRITE_SECTORS_NORETRY 0x31 -#define IDE_COMMAND_DIAGNOSTIC 0x90 -#define IDE_COMMAND_SET_CONFIG 0x91 -#define IDE_COMMAND_READ_MULTIPLE 0xc4 -#define IDE_COMMAND_WRITE_MULTIPLE 0xc5 -#define IDE_COMMAND_SET_BLOCK_COUNT 0xc6 -#define IDE_COMMAND_READ_DMA 0xc8 -#define IDE_COMMAND_WRITE_DMA 0xca -#define IDE_COMMAND_IDENTIFY_DEVICE 0xec -#define IDE_COMMAND_SET_FEATURES 0xef -#define IDE_COMMAND_SECURITY_UNLOCK 0xf2 -#define IDE_COMMAND_SET_MAX 0xf9 -#define IDE_COMMAND_VERIFY_SECTORS 0x40 -#define IDE_COMMAND_VERIFY_SECTORS_NORETRY 0x41 -#define IDE_COMMAND_ATAPI_IDENTIFY 0xa1 -#define IDE_COMMAND_RECALIBRATE 0x10 -#define IDE_COMMAND_SEEK 0x70 -#define IDE_COMMAND_IDLE_IMMEDIATE 0xe1 -#define IDE_COMMAND_IDLE 0xe3 - -#define IDE_DEVICE_CONTROL_NIEN 0x02 -#define IDE_DEVICE_CONTROL_SRST 0x04 - -enum -{ - TID_NULL, - TID_BUSY, -}; - -enum -{ - PARAM_RESET, - PARAM_DETECT_DEVICE1, - PARAM_DIAGNOSTIC, - PARAM_WAIT_FOR_PDIAG, - PARAM_COMMAND -}; - ata_mass_storage_device::ata_mass_storage_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source) - : device_t(mconfig, type, name, tag, owner, clock, shortname, source), - ata_device_interface(mconfig, *this), - device_slot_card_interface(mconfig, *this), + : ata_hle_device(mconfig, type, name, tag, owner, clock, shortname, source), m_can_identify_device(0), - m_csel(0), - m_daspin(0), - m_daspout(0), - m_dmack(0), - m_dmarq(0), - m_irq(0), - m_pdiagin(0), - m_pdiagout(0), m_master_password(NULL), m_user_password(NULL) { } -void ata_mass_storage_device::update_irq() -{ - if (device_selected() && (m_device_control & IDE_DEVICE_CONTROL_NIEN) == 0) - m_irq_handler(m_irq); - else - m_irq_handler(CLEAR_LINE); -} - -void ata_mass_storage_device::set_irq(int state) -{ - if (m_irq != state) - { - m_irq = state; - - if (state == ASSERT_LINE) - LOG(("IDE interrupt assert\n")); - else - LOG(("IDE interrupt clear\n")); - - update_irq(); - } -} - -void ata_mass_storage_device::set_dmarq(int state) -{ - if (m_dmarq != state) - { - m_dmarq = state; - - m_dmarq_handler(state); - } -} - -void ata_mass_storage_device::set_dasp(int state) -{ - if (m_daspout != state) - { - m_daspout = state; - - m_dasp_handler(state); - } -} - -void ata_mass_storage_device::set_pdiag(int state) -{ - if (m_pdiagout != state) - { - m_pdiagout = state; - - m_pdiag_handler(state); - } -} - -WRITE_LINE_MEMBER( ata_mass_storage_device::write_csel ) -{ - m_csel = state; -} - -WRITE_LINE_MEMBER( ata_mass_storage_device::write_dasp ) -{ - m_daspin = state; -} - -WRITE_LINE_MEMBER( ata_mass_storage_device::write_dmack ) -{ - m_dmack = state; -} - -WRITE_LINE_MEMBER( ata_mass_storage_device::write_pdiag ) -{ - m_pdiagin = state; - - if (m_pdiagin == ASSERT_LINE && m_busy_timer->param() == PARAM_WAIT_FOR_PDIAG) - { - stop_busy(); - finished_diagnostic(); - } -} - /************************************* * * Compute the LBA address @@ -376,208 +224,93 @@ void ata_mass_storage_device::ide_build_identify_device() void ata_mass_storage_device::device_start() { - m_irq_handler.resolve_safe(); - m_dmarq_handler.resolve_safe(); - m_dasp_handler.resolve_safe(); - m_pdiag_handler.resolve_safe(); - - save_item(NAME(m_buffer)); - save_item(NAME(m_buffer_offset)); - save_item(NAME(m_error)); - 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)); + ata_hle_device::device_start(); save_item(NAME(m_can_identify_device)); save_item(NAME(m_identify_device)); 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_block_count)); - - /* create a timer for timing status */ - m_last_status_timer = timer_alloc(TID_NULL); - m_busy_timer = timer_alloc(TID_BUSY); -} - -void ata_mass_storage_device::device_reset() -{ - /* reset the drive state */ - set_dasp(CLEAR_LINE); - set_dmarq(CLEAR_LINE); - set_irq(CLEAR_LINE); - set_pdiag(CLEAR_LINE); - - m_status = 0; - m_device_control = 0; - m_resetting = true; - - if (m_csel == 0) - { - start_busy(DETECT_DEVICE1_TIME, PARAM_DETECT_DEVICE1); - } - else - { - set_dasp(ASSERT_LINE); - soft_reset(); - } } void ata_mass_storage_device::soft_reset() { - m_buffer_offset = 0; + ata_hle_device::soft_reset(); + + m_status |= IDE_STATUS_DSC; + m_master_password_enable = (m_master_password != NULL); m_user_password_enable = (m_user_password != NULL); - - m_status = IDE_STATUS_DSC; - - if (is_ready()) - { - m_status |= IDE_STATUS_DRDY; - } - - start_busy(DIAGNOSTIC_TIME, PARAM_DIAGNOSTIC); } void ata_mass_storage_device::perform_diagnostic() { if (m_can_identify_device) - { m_error = IDE_ERROR_DIAGNOSTIC_PASSED; - - if (m_csel == 1) - set_pdiag(ASSERT_LINE); - } - else - m_error = IDE_ERROR_DIAGNOSTIC_FAILED; - - if (m_csel == 0 && !m_single_device && m_pdiagin == CLEAR_LINE) - start_busy(DEVICE1_PDIAG_TIME, PARAM_WAIT_FOR_PDIAG); - else - finished_diagnostic(); } -void ata_mass_storage_device::finished_diagnostic() +void ata_mass_storage_device::signature() { m_sector_count = 1; m_sector_number = 1; m_cylinder_low = 0; m_cylinder_high = 0; m_device_head = 0; - - m_resetting = false; } - -void ata_mass_storage_device::start_busy(attotime time, int param) +void ata_mass_storage_device::finished_command() { - m_status |= IDE_STATUS_BSY; - m_busy_timer->adjust(time, param); -} - -void ata_mass_storage_device::stop_busy() -{ - m_status &= ~IDE_STATUS_BSY; - m_busy_timer->adjust(attotime::never); -} - -void ata_mass_storage_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch(id) + switch (m_command) { - case TID_BUSY: - m_status &= ~IDE_STATUS_BSY; - - finished_busy(param); - break; - } -} - -void ata_mass_storage_device::finished_busy(int param) -{ - switch (param) - { - case PARAM_DETECT_DEVICE1: - m_single_device = (m_daspin == CLEAR_LINE); - soft_reset(); - break; - - case PARAM_DIAGNOSTIC: - perform_diagnostic(); - break; - - case PARAM_WAIT_FOR_PDIAG: - m_error |= 0x80; - finished_diagnostic(); - break; - - case PARAM_COMMAND: - switch (m_command) + case IDE_COMMAND_IDENTIFY_DEVICE: + if (m_can_identify_device) { - case IDE_COMMAND_DIAGNOSTIC: - perform_diagnostic(); - - if (m_csel == 0) - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_IDENTIFY_DEVICE: - if (m_can_identify_device) - { - memcpy(m_buffer, m_identify_device, sizeof(m_buffer)); - m_status |= IDE_STATUS_DRQ; - } - else - { - m_status |= IDE_STATUS_ERR; - m_error = IDE_ERROR_NONE; - } - - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_SET_CONFIG: - set_geometry(m_sector_count,(m_device_head & IDE_DEVICE_HEAD_HS) + 1); - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_READ_SECTORS: - case IDE_COMMAND_READ_SECTORS_NORETRY: - case IDE_COMMAND_READ_MULTIPLE: - case IDE_COMMAND_VERIFY_SECTORS: - case IDE_COMMAND_VERIFY_SECTORS_NORETRY: - case IDE_COMMAND_READ_DMA: - read_sector_done(); - break; - - case IDE_COMMAND_WRITE_SECTORS: - case IDE_COMMAND_WRITE_SECTORS_NORETRY: - case IDE_COMMAND_WRITE_MULTIPLE: - case IDE_COMMAND_WRITE_DMA: - write_sector_done(); - break; - - case IDE_COMMAND_RECALIBRATE: - set_irq(ASSERT_LINE); - break; - - case IDE_COMMAND_SET_FEATURES: - set_irq(ASSERT_LINE); - break; - - default: - logerror( "finished_busy(%d) unhandled command %02x\n", param, m_command ); - break; + memcpy(m_buffer, m_identify_device, m_buffer_size); + m_status |= IDE_STATUS_DRQ; } + else + { + m_status |= IDE_STATUS_ERR; + m_error = IDE_ERROR_NONE; + } + + set_irq(ASSERT_LINE); + break; + + case IDE_COMMAND_SET_CONFIG: + set_geometry(m_sector_count,(m_device_head & IDE_DEVICE_HEAD_HS) + 1); + set_irq(ASSERT_LINE); + break; + + case IDE_COMMAND_READ_SECTORS: + case IDE_COMMAND_READ_SECTORS_NORETRY: + case IDE_COMMAND_READ_MULTIPLE: + case IDE_COMMAND_VERIFY_SECTORS: + case IDE_COMMAND_VERIFY_SECTORS_NORETRY: + case IDE_COMMAND_READ_DMA: + finished_read(); + break; + + case IDE_COMMAND_WRITE_SECTORS: + case IDE_COMMAND_WRITE_SECTORS_NORETRY: + case IDE_COMMAND_WRITE_MULTIPLE: + case IDE_COMMAND_WRITE_DMA: + finished_write(); + break; + + case IDE_COMMAND_RECALIBRATE: + set_irq(ASSERT_LINE); + break; + + case IDE_COMMAND_SET_FEATURES: + set_irq(ASSERT_LINE); + break; + + default: + ata_hle_device::finished_command(); + break; } } @@ -656,17 +389,6 @@ void ata_mass_storage_device::security_error() * *************************************/ -void ata_mass_storage_device::read_buffer_empty() -{ - /* reset the totals */ - m_buffer_offset = 0; - - m_status &= ~IDE_STATUS_DRQ; - set_dmarq(CLEAR_LINE); - - fill_buffer(); -} - void ata_mass_storage_device::fill_buffer() { switch (m_command) @@ -675,25 +397,31 @@ void ata_mass_storage_device::fill_buffer() break; default: - if (m_master_password_enable || m_user_password_enable) - { - security_error(); - } - else - { - /* if there is more data to read, keep going */ - if (m_sector_count > 0) - m_sector_count--; + /* if there is more data to read, keep going */ + if (m_sector_count > 0) + m_sector_count--; - if (m_sector_count > 0) - read_next_sector(); + if (m_sector_count > 0) + { + set_dasp(ASSERT_LINE); + + if (m_command == IDE_COMMAND_READ_MULTIPLE) + { + if (m_sectors_until_int != 1) + /* make ready now */ + finished_read(); + else + start_busy(TIME_MULTIPLE_SECTORS, PARAM_COMMAND); + } + else + start_busy(TIME_PER_SECTOR, PARAM_COMMAND); } break; } } -void ata_mass_storage_device::read_sector_done() +void ata_mass_storage_device::finished_read() { int lba = lba_address(), count = 0; @@ -747,86 +475,38 @@ void ata_mass_storage_device::read_sector_done() void ata_mass_storage_device::read_first_sector() { - set_dasp(ASSERT_LINE); - - /* just set a timer */ - if (m_command == IDE_COMMAND_READ_MULTIPLE) + if (m_master_password_enable || m_user_password_enable) { - int new_lba = lba_address(); - attotime seek_time; - - if (new_lba == m_cur_lba || new_lba == m_cur_lba + 1) - start_busy(TIME_NO_SEEK_MULTISECTOR, PARAM_COMMAND); - else - start_busy(TIME_SEEK_MULTISECTOR, PARAM_COMMAND); - - m_cur_lba = new_lba; + security_error(); } else - start_busy(TIME_PER_SECTOR, PARAM_COMMAND); -} - - -void ata_mass_storage_device::read_next_sector() -{ - set_dasp(ASSERT_LINE); - - if (m_command == IDE_COMMAND_READ_MULTIPLE) { - if (m_sectors_until_int != 1) - /* make ready now */ - read_sector_done(); + set_dasp(ASSERT_LINE); + + /* just set a timer */ + if (m_command == IDE_COMMAND_READ_MULTIPLE) + { + int new_lba = lba_address(); + attotime seek_time; + + if (new_lba == m_cur_lba || new_lba == m_cur_lba + 1) + start_busy(TIME_NO_SEEK_MULTISECTOR, PARAM_COMMAND); + else + start_busy(TIME_SEEK_MULTISECTOR, PARAM_COMMAND); + + m_cur_lba = new_lba; + } else - start_busy(TIME_MULTIPLE_SECTORS, PARAM_COMMAND); + start_busy(TIME_PER_SECTOR, PARAM_COMMAND); } - else - start_busy(TIME_PER_SECTOR, PARAM_COMMAND); } - - /************************************* * * Sector writing * *************************************/ -void ata_mass_storage_device::continue_write() -{ - /* reset the totals */ - m_buffer_offset = 0; - - set_dasp(ASSERT_LINE); - - if (m_command == IDE_COMMAND_WRITE_MULTIPLE) - { - if (m_sectors_until_int != 1) - { - /* ready to write now */ - write_sector_done(); - } - else - { - /* set a timer to do the write */ - start_busy(TIME_PER_SECTOR, PARAM_COMMAND); - } - } - else - { - /* set a timer to do the write */ - start_busy(TIME_PER_SECTOR, PARAM_COMMAND); - } -} - - -void ata_mass_storage_device::write_buffer_full() -{ - m_status &= ~IDE_STATUS_DRQ; - set_dmarq(CLEAR_LINE); - - process_buffer(); -} - void ata_mass_storage_device::process_buffer() { if (m_command == IDE_COMMAND_SECURITY_UNLOCK) @@ -861,12 +541,31 @@ void ata_mass_storage_device::process_buffer() } else { - continue_write(); + set_dasp(ASSERT_LINE); + + if (m_command == IDE_COMMAND_WRITE_MULTIPLE) + { + if (m_sectors_until_int != 1) + { + /* ready to write now */ + finished_write(); + } + else + { + /* set a timer to do the write */ + start_busy(TIME_PER_SECTOR, PARAM_COMMAND); + } + } + else + { + /* set a timer to do the write */ + start_busy(TIME_PER_SECTOR, PARAM_COMMAND); + } } } -void ata_mass_storage_device::write_sector_done() +void ata_mass_storage_device::finished_write() { int lba = lba_address(), count = 0; @@ -922,8 +621,11 @@ void ata_mass_storage_device::write_sector_done() * *************************************/ -bool ata_mass_storage_device::process_command() +void ata_mass_storage_device::process_command() { + m_sectors_until_int = 0; + m_buffer_size = IDE_DISK_SECTOR_SIZE; + switch (m_command) { case IDE_COMMAND_READ_SECTORS: @@ -935,7 +637,7 @@ bool ata_mass_storage_device::process_command() /* start the read going */ read_first_sector(); - return true; + return; case IDE_COMMAND_READ_MULTIPLE: LOGPRINT(("IDE Read multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", @@ -945,7 +647,7 @@ bool ata_mass_storage_device::process_command() /* start the read going */ read_first_sector(); - return true; + return; case IDE_COMMAND_VERIFY_SECTORS: case IDE_COMMAND_VERIFY_SECTORS_NORETRY: @@ -957,7 +659,7 @@ bool ata_mass_storage_device::process_command() /* start the read going */ read_first_sector(); - return true; + return; case IDE_COMMAND_READ_DMA: LOGPRINT(("IDE Read multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", @@ -968,7 +670,7 @@ bool ata_mass_storage_device::process_command() /* start the read going */ read_first_sector(); - return true; + return; case IDE_COMMAND_WRITE_SECTORS: case IDE_COMMAND_WRITE_SECTORS_NORETRY: @@ -980,7 +682,7 @@ bool ata_mass_storage_device::process_command() /* mark the buffer ready */ m_status |= IDE_STATUS_DRQ; - return true; + return; case IDE_COMMAND_WRITE_MULTIPLE: LOGPRINT(("IDE Write multiple block: C=%d H=%d S=%d LBA=%d count=%d\n", @@ -991,7 +693,7 @@ bool ata_mass_storage_device::process_command() /* mark the buffer ready */ m_status |= IDE_STATUS_DRQ; - return true; + return; case IDE_COMMAND_WRITE_DMA: LOGPRINT(("IDE Write multiple DMA: C=%d H=%d S=%d LBA=%d count=%d\n", @@ -1005,7 +707,7 @@ bool ata_mass_storage_device::process_command() /* start the read going */ set_dmarq(ASSERT_LINE); - return true; + return; case IDE_COMMAND_SECURITY_UNLOCK: LOGPRINT(("IDE Security Unlock\n")); @@ -1014,45 +716,41 @@ bool ata_mass_storage_device::process_command() m_status |= IDE_STATUS_DRQ; set_irq(ASSERT_LINE); - return true; + return; case IDE_COMMAND_IDENTIFY_DEVICE: LOGPRINT(("IDE Identify device\n")); start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND); - return true; - - case IDE_COMMAND_DIAGNOSTIC: - start_busy(DIAGNOSTIC_TIME, PARAM_COMMAND); - return true; + return; case IDE_COMMAND_RECALIBRATE: start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND); - return true; + return; case IDE_COMMAND_IDLE: /* signal an interrupt */ set_irq(ASSERT_LINE); - return true; + return; case IDE_COMMAND_SET_CONFIG: LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", (m_device_head & IDE_DEVICE_HEAD_HS) + 1, m_sector_count)); start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND); - return true; + return; case IDE_COMMAND_SET_MAX: LOGPRINT(("IDE Set max (%02X %02X %02X %02X %02X)\n", m_feature, m_sector_count & 0xff, m_sector_number, m_cylinder_low, m_cylinder_high)); /* signal an interrupt */ set_irq(ASSERT_LINE); - return true; + return; 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)); start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND); - return true; + return; case IDE_COMMAND_SET_BLOCK_COUNT: LOGPRINT(("IDE Set block count (%02X)\n", m_sector_count)); @@ -1061,454 +759,15 @@ bool ata_mass_storage_device::process_command() /* signal an interrupt */ set_irq(ASSERT_LINE); - return true; + return; case IDE_COMMAND_SEEK: /* signal an interrupt */ set_irq(ASSERT_LINE); - return true; - - default: - return false; - } -} - -UINT16 ata_mass_storage_device::read_dma() -{ - UINT16 result = 0xffff; - - if (device_selected()) - { - if (!m_dmack) - { - logerror( "%s: dev %d read_dma ignored (!DMACK)\n", machine().describe_context(), dev() ); - } - else if( !m_dmarq) - { - logerror( "%s: dev %d read_dma ignored (!DMARQ)\n", machine().describe_context(), dev() ); - } - else if (m_status & IDE_STATUS_BSY) - { - logerror( "%s: dev %d read_dma ignored (BSY)\n", machine().describe_context(), dev() ); - } - else if (!(m_status & IDE_STATUS_DRQ)) - { - logerror( "%s: dev %d read_dma ignored (!DRQ)\n", machine().describe_context(), dev() ); - } - else - { - result = m_buffer[m_buffer_offset++]; - result |= m_buffer[m_buffer_offset++] << 8; - - if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) - { - LOG(("%s:IDE completed DMA read\n", machine().describe_context())); - read_buffer_empty(); - } - } + return; } - return result; -} - -READ16_MEMBER( ata_mass_storage_device::read_cs0 ) -{ - /* logit */ -// 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)); - - UINT16 result = 0xffff; - - if (device_selected() || m_single_device) - { - if (m_dmack) - { - logerror( "%s: dev %d read_cs0 %04x %04x ignored (DMACK)\n", machine().describe_context(), dev(), offset, mem_mask ); - } - else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_STATUS_R) - { - // ATA5 spec says status reads should also go through here, but this breaks Primal Rage 2. - // Real hardware might work due to read ahead in the vt83c461. - if (device_selected()) - { - switch (offset) - { - case IDE_CS0_DATA_RW: - logerror( "%s: dev %d read_cs0 %04x %04x ignored (BSY)\n", machine().describe_context(), dev(), offset, mem_mask ); - break; - - default: - result = m_status; - - 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) - { - /* read data if there's data to be read */ - case IDE_CS0_DATA_RW: - if (device_selected()) - { - if (m_status & IDE_STATUS_DRQ) - { - /* fetch the correct amount of data */ - result = m_buffer[m_buffer_offset++]; - if (mem_mask == 0xffff) - result |= m_buffer[m_buffer_offset++] << 8; - - /* if we're at the end of the buffer, handle it */ - if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) - { - LOG(("%s:IDE completed PIO read\n", machine().describe_context())); - read_buffer_empty(); - } - } - } - else - { - result = 0; - } - break; - - /* return the current error */ - case IDE_CS0_ERROR_R: - result = m_error; - break; - - /* return the current sector count */ - case IDE_CS0_SECTOR_COUNT_RW: - result = m_sector_count; - break; - - /* return the current sector */ - case IDE_CS0_SECTOR_NUMBER_RW: - result = m_sector_number; - break; - - /* return the current cylinder LSB */ - case IDE_CS0_CYLINDER_LOW_RW: - result = m_cylinder_low; - break; - - /* return the current cylinder MSB */ - case IDE_CS0_CYLINDER_HIGH_RW: - result = m_cylinder_high; - break; - - /* return the current head */ - case IDE_CS0_DEVICE_HEAD_RW: - result = m_device_head; - break; - - /* return the current status and clear any pending interrupts */ - case IDE_CS0_STATUS_R: - if (device_selected()) - { - result = m_status; - - if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) - { - result |= IDE_STATUS_IDX; - m_last_status_timer->adjust(attotime::never); - } - - if (!(m_status & IDE_STATUS_DRDY) && is_ready()) - m_status |= IDE_STATUS_DRDY; - - set_irq(CLEAR_LINE); - } - else - { - result = 0; - } - break; - - /* log anything else */ - default: - logerror("%s:unknown IDE cs0 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); - break; - } - } - } - - /* return the result */ - return result; -} - -READ16_MEMBER( ata_mass_storage_device::read_cs1 ) -{ - /* logit */ -// if (offset != IDE_CS1_ALTERNATE_STATUS_R) - LOG(("%s:IDE cs1 read at %X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask)); - - UINT16 result = 0xffff; - - if (device_selected() || m_single_device) - { - if (m_dmack) - { - logerror( "%s: dev %d read_cs1 %04x %04x ignored (DMACK)\n", machine().describe_context(), dev(), offset, mem_mask ); - } - else - { - switch (offset) - { - case IDE_CS1_ALTERNATE_STATUS_R: - if( device_selected() ) - { - /* return the current status but don't clear interrupts */ - result = m_status; - if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) - { - result |= IDE_STATUS_IDX; - m_last_status_timer->adjust(attotime::never); - } - } - else - { - result = 0; - } - break; - - /* log anything else */ - default: - logerror("%s:unknown IDE cs1 read at %03X, mem_mask=%d\n", machine().describe_context(), offset, mem_mask); - break; - } - } - } - - /* return the result */ - return result; -} - -void ata_mass_storage_device::write_dma( UINT16 data ) -{ - if (device_selected()) - { - if (!m_dmack) - { - logerror( "%s: dev %d write_dma %04x ignored (!DMACK)\n", machine().describe_context(), dev(), data ); - } - else if( !m_dmarq) - { - logerror( "%s: dev %d write_dma %04x ignored (!DMARQ)\n", machine().describe_context(), dev(), data ); - } - else if (m_status & IDE_STATUS_BSY) - { - logerror( "%s: dev %d write_dma %04x ignored (BSY)\n", machine().describe_context(), dev(), data ); - } - else if (!(m_status & IDE_STATUS_DRQ)) - { - logerror( "%s: dev %d write_dma %04x ignored (!DRQ)\n", machine().describe_context(), dev(), data ); - } - else - { - m_buffer[m_buffer_offset++] = data; - m_buffer[m_buffer_offset++] = data >> 8; - - /* if we're at the end of the buffer, handle it */ - if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) - { - LOG(("%s:IDE completed DMA write\n", machine().describe_context())); - write_buffer_full(); - } - } - } -} - -WRITE16_MEMBER( ata_mass_storage_device::write_cs0 ) -{ - /* 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)); - // fprintf(stderr, "ide write %03x %02x mem_mask=%d\n", offset, data, size); - - if (m_dmack) - { - logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), dev(), offset, data, mem_mask ); - } - else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_COMMAND_W) - { - logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (BSY) command %02x\n", machine().describe_context(), dev(), offset, data, mem_mask, m_command ); - } - else if ((m_status & IDE_STATUS_DRQ) && offset != IDE_CS0_DATA_RW && offset != IDE_CS0_COMMAND_W) - { - logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (DRQ) command %02x\n", machine().describe_context(), dev(), offset, data, mem_mask, m_command ); - } - else - { - UINT8 old; - - switch (offset) - { - /* write data */ - case IDE_CS0_DATA_RW: - if( device_selected() ) - { - if (!(m_status & IDE_STATUS_DRQ)) - { - logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (!DRQ)\n", machine().describe_context(), dev(), offset, data, mem_mask ); - } - else - { - /* store the correct amount of data */ - m_buffer[m_buffer_offset++] = data; - if (mem_mask == 0xffff) - m_buffer[m_buffer_offset++] = data >> 8; - - /* if we're at the end of the buffer, handle it */ - if (m_buffer_offset >= IDE_DISK_SECTOR_SIZE) - { - LOG(("%s:IDE completed PIO write\n", machine().describe_context())); - write_buffer_full(); - } - } - } - break; - - case IDE_CS0_FEATURE_W: - m_feature = data; - break; - - /* sector count */ - case IDE_CS0_SECTOR_COUNT_RW: - m_sector_count = data ? data : 256; - break; - - /* current sector */ - case IDE_CS0_SECTOR_NUMBER_RW: - m_sector_number = data; - break; - - /* current cylinder LSB */ - case IDE_CS0_CYLINDER_LOW_RW: - m_cylinder_low = data; - break; - - /* current cylinder MSB */ - case IDE_CS0_CYLINDER_HIGH_RW: - m_cylinder_high = data; - break; - - /* current head */ - case IDE_CS0_DEVICE_HEAD_RW: - old = m_device_head; - m_device_head = data; - - if ((m_device_head ^ old) & IDE_DEVICE_HEAD_DRV) - update_irq(); - break; - - /* command */ - case IDE_CS0_COMMAND_W: - // Packet devices can accept DEVICE RESET when BSY or DRQ is set. - if (m_status & IDE_STATUS_BSY) - { - logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (BSY) command %02x\n", machine().describe_context(), dev(), offset, data, mem_mask, m_command ); - } - else if (m_status & IDE_STATUS_DRQ) - { - logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (DRQ) command %02x\n", machine().describe_context(), dev(), offset, data, mem_mask, m_command ); - } - else if (device_selected() || m_command == IDE_COMMAND_DIAGNOSTIC) - { - m_command = data; - - /* implicitly clear interrupts & dmarq here */ - set_irq(CLEAR_LINE); - set_dmarq(CLEAR_LINE); - - m_buffer_offset = 0; - m_sectors_until_int = 0; - - set_dasp(CLEAR_LINE); - m_status &= ~IDE_STATUS_DRQ; - 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; - - default: - logerror("%s:unknown IDE cs0 write at %03X = %04x, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask); - break; - } - } -} - -WRITE16_MEMBER( ata_mass_storage_device::write_cs1 ) -{ - /* logit */ - LOG(("%s:IDE cs1 write to %X = %08X, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask)); - - if (m_dmack) - { - logerror( "%s: dev %d write_cs1 %04x %04x %04x ignored (DMACK)\n", machine().describe_context(), dev(), offset, data, mem_mask ); - } - else - { - UINT8 old; - - switch (offset) - { - /* adapter control */ - case IDE_CS1_DEVICE_CONTROL_W: - old = m_device_control; - m_device_control = data; - - if ((m_device_control ^ old) & IDE_DEVICE_CONTROL_NIEN) - update_irq(); - - if ((m_device_control ^ old) & IDE_DEVICE_CONTROL_SRST) - { - if (m_device_control & IDE_DEVICE_CONTROL_SRST) - { - if (m_resetting) - { - logerror( "%s: dev %d write_cs1 %04x %04x %04x ignored (RESET)\n", machine().describe_context(), dev(), offset, data, mem_mask ); - } - else - { - set_dasp(CLEAR_LINE); - set_dmarq(CLEAR_LINE); - set_irq(CLEAR_LINE); - set_pdiag(CLEAR_LINE); - - start_busy(attotime::never, PARAM_RESET); - } - } - else if (m_busy_timer->param() == PARAM_RESET) - { - soft_reset(); - } - } - break; - - default: - logerror("%s:unknown IDE cs1 write at %03X = %04x, mem_mask=%d\n", machine().describe_context(), offset, data, mem_mask); - break; - } - } + ata_hle_device::process_command(); } //************************************************************************** @@ -1534,6 +793,14 @@ ide_hdd_device::ide_hdd_device(const machine_config &mconfig, device_type type, { } +void ide_hdd_device::device_start() +{ + ata_mass_storage_device::device_start(); + + /* create a timer for timing status */ + m_last_status_timer = timer_alloc(TID_NULL); +} + //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- @@ -1566,6 +833,19 @@ void ide_hdd_device::device_reset() ata_mass_storage_device::device_reset(); } +UINT8 ide_hdd_device::calculate_status() +{ + UINT8 result = ata_hle_device::calculate_status(); + + if (m_last_status_timer->elapsed() > TIME_PER_ROTATION) + { + result |= IDE_STATUS_IDX; + m_last_status_timer->adjust(attotime::never); + } + + return result; +} + //------------------------------------------------- // machine_config_additions - device-specific // machine configurations diff --git a/src/emu/machine/idehd.h b/src/emu/machine/idehd.h index 3ca8285a16b..9e4b843a2e2 100644 --- a/src/emu/machine/idehd.h +++ b/src/emu/machine/idehd.h @@ -1,68 +1,28 @@ -#include "emu.h" -#include "atadev.h" +/*************************************************************************** + + idehd.h + + IDE Harddisk + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#pragma once + +#ifndef __IDEHD_H__ +#define __IDEHD_H__ + +#include "atahle.h" #include "harddisk.h" #include "imagedev/harddriv.h" -#define IDE_DISK_SECTOR_SIZE 512 - -// Error -#define IDE_STATUS_ERR (0x01) - -// Index -#define IDE_STATUS_IDX (0x02) - -// 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_DIAGNOSTIC_OK 0x01 -#define IDE_ERROR_TRACK0_NOT_FOUND 0x02 -#define IDE_ERROR_UNKNOWN_COMMAND 0x04 -#define IDE_ERROR_BAD_LOCATION 0x10 -#define IDE_ERROR_BAD_SECTOR 0x80 - -#define IDE_ERROR_DIAGNOSTIC_FAILED 0x00 -#define IDE_ERROR_DIAGNOSTIC_PASSED 0x01 -#define IDE_ERROR_DIAGNOSTIC_DEVICE1_FAILED 0x81 - -#define IDE_DEVICE_HEAD_HS 0x0f -#define IDE_DEVICE_HEAD_DRV 0x10 -#define IDE_DEVICE_HEAD_L 0x40 - -class ata_mass_storage_device : public device_t, - public ata_device_interface, - public device_slot_card_interface +class ata_mass_storage_device : public ata_hle_device { public: ata_mass_storage_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock,const char *shortname, const char *source); - virtual UINT16 read_dma(); - virtual DECLARE_READ16_MEMBER(read_cs0); - virtual DECLARE_READ16_MEMBER(read_cs1); - - virtual void write_dma(UINT16 data); - virtual DECLARE_WRITE16_MEMBER(write_cs0); - virtual DECLARE_WRITE16_MEMBER(write_cs1); - virtual DECLARE_WRITE_LINE_MEMBER(write_csel); - virtual DECLARE_WRITE_LINE_MEMBER(write_dasp); - virtual DECLARE_WRITE_LINE_MEMBER(write_dmack); - virtual DECLARE_WRITE_LINE_MEMBER(write_pdiag); - UINT8 *identify_device_buffer() { return m_identify_device; } void set_master_password(const UINT8 *password) @@ -71,7 +31,6 @@ public: m_master_password_enable = (password != NULL); } - void set_user_password(const UINT8 *password) { m_user_password = password; @@ -80,39 +39,21 @@ public: protected: virtual void device_start(); - virtual void device_reset(); - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); - virtual bool is_ready() { return true; } virtual int read_sector(UINT32 lba, void *buffer) = 0; virtual int write_sector(UINT32 lba, const void *buffer) = 0; - int dev() { return (m_device_head & IDE_DEVICE_HEAD_DRV) >> 4; } - bool device_selected() { return m_csel == dev(); } - - void set_irq(int state); - void set_dmarq(int state); - void set_dasp(int state); - void set_pdiag(int state); void ide_build_identify_device(); - virtual bool process_command(); + static const int IDE_DISK_SECTOR_SIZE = 512; + virtual int sector_length() { return IDE_DISK_SECTOR_SIZE; } virtual void process_buffer(); virtual void fill_buffer(); - virtual void finished_busy(int param); - - 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; + virtual bool is_ready() { return true; } + virtual void process_command(); + virtual void finished_command(); + virtual void perform_diagnostic(); + virtual void signature(); int m_can_identify_device; UINT8 m_identify_device[IDE_DISK_SECTOR_SIZE]; @@ -123,34 +64,12 @@ protected: private: UINT32 lba_address(); void set_geometry(UINT8 sectors, UINT8 heads) { m_num_sectors = sectors; m_num_heads = heads; } - void read_sector_done(); - void write_sector_done(); - void read_next_sector(); - void continue_write(); + void finished_read(); + void finished_write(); void next_sector(); void security_error(); - void continue_read(); void read_first_sector(); - void read_buffer_empty(); - void write_buffer_full(); - void update_irq(); - void start_busy(attotime time, int param); - void stop_busy(); void soft_reset(); - void perform_diagnostic(); - void finished_diagnostic(); - - int m_csel; - int m_daspin; - int m_daspout; - int m_dmack; - int m_dmarq; - int m_irq; - int m_pdiagin; - int m_pdiagout; - - bool m_resetting; - bool m_single_device; UINT32 m_cur_lba; UINT16 m_block_count; @@ -160,9 +79,6 @@ private: UINT8 m_user_password_enable; const UINT8 * m_master_password; const UINT8 * m_user_password; - - emu_timer * m_last_status_timer; - emu_timer * m_busy_timer; }; // ======================> ide_hdd_device @@ -179,17 +95,29 @@ public: protected: // device-level overrides + virtual void device_start(); virtual void device_reset(); // optional information overrides virtual machine_config_constructor device_mconfig_additions() const; + virtual UINT8 calculate_status(); + chd_file *m_handle; hard_disk_file *m_disk; + enum + { + TID_NULL = TID_BUSY + 1, + }; + private: required_device m_image; + + emu_timer * m_last_status_timer; }; // device type definition extern const device_type IDE_HARDDISK; + +#endif diff --git a/src/emu/machine/machine.mak b/src/emu/machine/machine.mak index f0a4f51ee7c..8a31c486968 100644 --- a/src/emu/machine/machine.mak +++ b/src/emu/machine/machine.mak @@ -530,13 +530,16 @@ endif #------------------------------------------------- # -#@src/emu/machine/idectrl.h,MACHINES += IDE -#@src/emu/machine/idehd.h,MACHINES += IDE +#@src/emu/machine/atadev.h,MACHINES += IDE +#@src/emu/machine/ataintf.h,MACHINES += IDE #------------------------------------------------- ifneq ($(filter IDE,$(MACHINES)),) -MACHINEOBJS += $(MACHINEOBJ)/ataintf.o MACHINEOBJS += $(MACHINEOBJ)/atadev.o +MACHINEOBJS += $(MACHINEOBJ)/atahle.o +MACHINEOBJS += $(MACHINEOBJ)/ataintf.o +MACHINEOBJS += $(MACHINEOBJ)/atapicdr.o +MACHINEOBJS += $(MACHINEOBJ)/atapihle.o MACHINEOBJS += $(MACHINEOBJ)/idectrl.o MACHINEOBJS += $(MACHINEOBJ)/idehd.o MACHINEOBJS += $(MACHINEOBJ)/vt83c461.o diff --git a/src/mess/drivers/at.c b/src/mess/drivers/at.c index 030bd8e7324..e2ea437521a 100644 --- a/src/mess/drivers/at.c +++ b/src/mess/drivers/at.c @@ -533,13 +533,6 @@ static MACHINE_CONFIG_START( xb42639, at_state ) MCFG_RAM_EXTRA_OPTIONS("2M,4M,8M,15M") MACHINE_CONFIG_END -//------------------------------------------------- -// DEVICE_INPUT_DEFAULTS( ide_2nd) -//------------------------------------------------- - -static DEVICE_INPUT_DEFAULTS_START( ide_2nd ) - DEVICE_INPUT_DEFAULTS("DSW", 0x01, 0x01) -DEVICE_INPUT_DEFAULTS_END static MACHINE_CONFIG_START( at386, at_state ) MCFG_CPU_ADD("maincpu", I386, 12000000) @@ -560,8 +553,7 @@ static MACHINE_CONFIG_START( at386, at_state ) MCFG_ISA16_SLOT_ADD("isabus","isa2", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD("isabus","isa3", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD("isabus","isa4", pc_isa16_cards, NULL, false) - MCFG_ISA16_SLOT_ADD("isabus","isa5", pc_isa16_cards, "ide_cd", false) //2nd-ary IDE - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("ide_cd", ide_2nd) + MCFG_ISA16_SLOT_ADD("isabus","isa5", pc_isa16_cards, NULL, false) MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) /* internal ram */ @@ -640,8 +632,7 @@ static MACHINE_CONFIG_START( at586, at586_state ) MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371ab:isabus","isa2", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371ab:isabus","isa3", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371ab:isabus","isa4", pc_isa16_cards, NULL, false) - MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371ab:isabus","isa5", pc_isa16_cards, "ide_cd", false) //2nd-ary IDE - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("ide_cd", ide_2nd) + MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371ab:isabus","isa5", pc_isa16_cards, NULL, false) MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) MACHINE_CONFIG_END @@ -664,8 +655,7 @@ static MACHINE_CONFIG_START( at586x3, at586_state ) MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371sb:isabus","isa2", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371sb:isabus","isa3", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371sb:isabus","isa4", pc_isa16_cards, NULL, false) - MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371sb:isabus","isa5", pc_isa16_cards, "ide_cd", false) //2nd-ary IDE - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("ide_cd", ide_2nd) + MCFG_ISA16_SLOT_ADD(":pcibus:1:i82371sb:isabus","isa5", pc_isa16_cards, NULL, false) MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) MACHINE_CONFIG_END diff --git a/src/mess/drivers/ct486.c b/src/mess/drivers/ct486.c index e4a67d4f607..603cec4b796 100644 --- a/src/mess/drivers/ct486.c +++ b/src/mess/drivers/ct486.c @@ -137,10 +137,6 @@ static const isa16bus_interface isabus_intf = DEVCB_DEVICE_LINE_MEMBER("cs4031", cs4031_device, dreq7_w), }; -static DEVICE_INPUT_DEFAULTS_START( ide_2nd ) - DEVICE_INPUT_DEFAULTS("DSW", 0x01, 0x01) -DEVICE_INPUT_DEFAULTS_END - static MACHINE_CONFIG_START( ct486, ct486_state ) MCFG_CPU_ADD("maincpu", I486, XTAL_25MHz) MCFG_CPU_PROGRAM_MAP(ct486_map) @@ -178,8 +174,7 @@ static MACHINE_CONFIG_START( ct486, ct486_state ) MCFG_ISA16_SLOT_ADD("isabus", "isa2", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD("isabus", "isa3", pc_isa16_cards, NULL, false) MCFG_ISA16_SLOT_ADD("isabus", "isa4", pc_isa16_cards, NULL, false) - MCFG_ISA16_SLOT_ADD("isabus", "isa5", pc_isa16_cards, "ide_cd", false) //2nd-ary IDE - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("ide_cd", ide_2nd) + MCFG_ISA16_SLOT_ADD("isabus", "isa5", pc_isa16_cards, NULL, false) // sound hardware MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mess/machine/isa_cards.c b/src/mess/machine/isa_cards.c index 585ad332aa5..0370b72209e 100644 --- a/src/mess/machine/isa_cards.c +++ b/src/mess/machine/isa_cards.c @@ -65,7 +65,6 @@ SLOT_INTERFACE_START( pc_isa16_cards ) SLOT_INTERFACE("fdcsmc", ISA8_FDC_SMC) // 16-bit SLOT_INTERFACE("ide", ISA16_IDE) - SLOT_INTERFACE("ide_cd", ISA16_IDE_CD) SLOT_INTERFACE("ne2000", NE2000) SLOT_INTERFACE("aha1542", AHA1542) SLOT_INTERFACE("gus",ISA16_GUS) diff --git a/src/mess/machine/isa_cards.h b/src/mess/machine/isa_cards.h index bacc2ea612a..20b05f48eb8 100644 --- a/src/mess/machine/isa_cards.h +++ b/src/mess/machine/isa_cards.h @@ -30,7 +30,6 @@ #include "machine/isa_wdxt_gen.h" #include "machine/isa_ide.h" #include "machine/isa_ide8.h" -#include "machine/isa_ide_cd.h" #include "machine/isa_aha1542.h" #include "machine/isa_wd1002a_wx1.h" diff --git a/src/mess/machine/isa_ide_cd.c b/src/mess/machine/isa_ide_cd.c deleted file mode 100644 index 266990f46fc..00000000000 --- a/src/mess/machine/isa_ide_cd.c +++ /dev/null @@ -1,484 +0,0 @@ -/*************************************************************************** - - ISA 16 bit IDE controller - -***************************************************************************/ - -#include "emu.h" -#include "isa_ide_cd.h" - -static void atapi_irq(device_t *device, int state) -{ - isa16_ide_cd_device *ide = downcast(device); - if (ide->is_primary()) { - ide->m_isa->irq14_w(state); - } else { - ide->m_isa->irq15_w(state); - } -} - -WRITE16_MEMBER( isa16_ide_cd_device::atapi_cmd_w ) -{ - if(data & 4) // ide reset - { - m_atapi_regs[ATAPI_REG_CMDSTATUS] = 0x00; - m_atapi_regs[ATAPI_REG_ERRFEAT] = 0x01; - m_atapi_regs[ATAPI_REG_INTREASON] = 0x01; // SECTOR_COUNT - m_atapi_regs[ATAPI_REG_SAMTAG] = 0x01; // SECTOR_NUMBER - m_atapi_regs[ATAPI_REG_COUNTLOW] = 0x14; // CYLINDER_LSB - m_atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb; // CYLINDER_MSB - m_atapi_regs[ATAPI_REG_DRIVESEL] = 0xA0; // HEAD_NUMBER - } -} - -READ16_MEMBER( isa16_ide_cd_device::atapi_status_r ) -{ - UINT8 *atapi_regs = m_atapi_regs; - int shift; - shift = 0; - switch(mem_mask) - { - case 0x000000ff: - break; - case 0x0000ff00: - shift=8; - break; - } - UINT32 data = atapi_regs[ATAPI_REG_CMDSTATUS]; - data <<= shift; - return data; -} - -READ16_MEMBER( isa16_ide_cd_device::atapi_r ) -{ - UINT8 *atapi_regs = m_atapi_regs; - //running_machine &machine = machine(); - int reg, data; - if (mem_mask == 0x0000ffff) // word-wide command read - { - //logerror("ATAPI: packet read = %02x%02x\n", m_atapi_data[m_atapi_data_ptr+1],m_atapi_data[m_atapi_data_ptr]); - - // assert IRQ and drop DRQ - if (m_atapi_data_ptr == 0 && m_atapi_data_len == 0) - { - // get the data from the device - if( m_atapi_xferlen > 0 ) - { - m_inserted_cdrom->ReadData( m_atapi_data, m_atapi_xferlen ); - m_atapi_data_len = m_atapi_xferlen; - } - - if (m_atapi_xfermod > MAX_TRANSFER_SIZE) - { - m_atapi_xferlen = MAX_TRANSFER_SIZE; - m_atapi_xfermod = m_atapi_xfermod - MAX_TRANSFER_SIZE; - } - else - { - m_atapi_xferlen = m_atapi_xfermod; - m_atapi_xfermod = 0; - } - - //verboselog\\( machine, 2, "atapi_r: atapi_xferlen=%d\n", m_atapi_xferlen ); - if( m_atapi_xferlen != 0 ) - { - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC; - atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO; - } - else - { - //logerror("ATAPI: dropping DRQ\n"); - atapi_regs[ATAPI_REG_CMDSTATUS] = 0; - atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO | ATAPI_INTREASON_COMMAND; - } - - atapi_regs[ATAPI_REG_COUNTLOW] = m_atapi_xferlen & 0xff; - atapi_regs[ATAPI_REG_COUNTHIGH] = (m_atapi_xferlen>>8)&0xff; - - atapi_irq(this, ASSERT_LINE); - } - - if( m_atapi_data_ptr < m_atapi_data_len ) - { - data = m_atapi_data[m_atapi_data_ptr++]; - data |= ( m_atapi_data[m_atapi_data_ptr++] << 8 ); - if( m_atapi_data_ptr >= m_atapi_data_len ) - { - m_atapi_data_ptr = 0; - m_atapi_data_len = 0; - - if( m_atapi_xferlen == 0 ) - { - atapi_regs[ATAPI_REG_CMDSTATUS] = 0; - atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO | ATAPI_INTREASON_COMMAND; - atapi_irq(this, ASSERT_LINE); - } - } - } - else - { - data = 0; - } - } - else - { - atapi_irq(this, CLEAR_LINE); - int shift; - shift = 0; - reg = offset<<1; - switch(mem_mask) - { - case 0x000000ff: - break; - case 0x0000ff00: - reg+=1; - shift=8; - break; - } - if (m_cur_drive==1) return 0x00; - data = atapi_regs[reg]; - //logerror("ATAPI: reg %d = %x (offset %x mask %x) [%08x][read]\n", reg, data, offset, mem_mask,m_maincpu->safe_pc()); - data <<= shift; - } - return data; -} - -WRITE16_MEMBER( isa16_ide_cd_device::atapi_w ) -{ - UINT8 *atapi_regs = m_atapi_regs; - UINT8 *atapi_data = m_atapi_data; - int reg; - if (mem_mask == 0x0000ffff) // word-wide command write - { - atapi_data[m_atapi_data_ptr++] = data & 0xff; - atapi_data[m_atapi_data_ptr++] = data >> 8; - - if (m_atapi_cdata_wait) - { - //logerror("ATAPI: waiting, ptr %d wait %d\n", m_atapi_data_ptr, m_atapi_cdata_wait); - if (m_atapi_data_ptr == m_atapi_cdata_wait) - { - // send it to the device - m_inserted_cdrom->WriteData( atapi_data, m_atapi_cdata_wait ); - - // assert IRQ - atapi_irq(this, ASSERT_LINE); - - // not sure here, but clear DRQ at least? - atapi_regs[ATAPI_REG_CMDSTATUS] = 0; - } - } - - else if ( m_atapi_data_ptr == 12 ) - { - int phase; - // reset data pointer for reading SCSI results - m_atapi_data_ptr = 0; - m_atapi_data_len = 0; - void *cdrom; - m_inserted_cdrom->GetDevice( &cdrom ); - bool checkready = false; - switch(atapi_data[0]&0xff) { - case 0x00 : - case 0x25 : - case 0x28 : - case 0x2b : - case 0x43 : - case 0xa8 : - case 0xad : - case 0xbe : - checkready = true; - break; - } - - if (checkready && cdrom_get_toc((cdrom_file *)cdrom)==NULL) - { - logerror("ATAPI: SCSI command %02x returned not ready\n", atapi_data[0]&0xff); - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRDY | ATAPI_STAT_CHECK; - atapi_regs[ATAPI_REG_ERRFEAT] = (2 << 4) | ATAPI_ERRFEAT_ABRT; - // assert IRQ - atapi_irq(this, ASSERT_LINE); - } else { - // send it to the SCSI device - m_inserted_cdrom->SetCommand( m_atapi_data, 12 ); - m_inserted_cdrom->ExecCommand( &m_atapi_xferlen ); - m_inserted_cdrom->GetPhase( &phase ); - - if (m_atapi_xferlen != -1) - { - logerror("ATAPI: SCSI command %02x %s %d bytes from the device\n", atapi_data[0]&0xff, (phase == SCSI_PHASE_DATAOUT) ? "requested" : "returned", m_atapi_xferlen); - // store the returned command length in the ATAPI regs, splitting into - // multiple transfers if necessary - m_atapi_xfermod = 0; - if (m_atapi_xferlen > MAX_TRANSFER_SIZE) - { - m_atapi_xfermod = m_atapi_xferlen - MAX_TRANSFER_SIZE; - m_atapi_xferlen = MAX_TRANSFER_SIZE; - } - - atapi_regs[ATAPI_REG_COUNTLOW] = m_atapi_xferlen & 0xff; - atapi_regs[ATAPI_REG_COUNTHIGH] = (m_atapi_xferlen>>8)&0xff; - - if (m_atapi_xferlen == 0) - { - // if no data to return, set the registers properly - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRDY; - atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO|ATAPI_INTREASON_COMMAND; - } - else - { - // indicate data ready: set DRQ and DMA ready, and IO in INTREASON - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_SERVDSC; - if(phase != SCSI_PHASE_DATAOUT) - atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_IO; - else - atapi_regs[ATAPI_REG_INTREASON] = 0; - } - - switch( phase ) - { - case SCSI_PHASE_DATAOUT: - m_atapi_cdata_wait = m_atapi_xferlen; - break; - } - - // perform special ATAPI processing of certain commands - switch (atapi_data[0]&0xff) - { - case 0x00: // BUS RESET / TEST UNIT READY - case 0xbb: // SET CDROM SPEED - atapi_regs[ATAPI_REG_CMDSTATUS] = 0; - break; - - case 0x45: // PLAY - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_BSY; - //m_atapi_timer->adjust( downcast(this)->cycles_to_attotime( ATAPI_CYCLES_PER_SECTOR ) ); - break; - } - - // assert IRQ - atapi_irq(this, ASSERT_LINE); - } - else - { - logerror("ATAPI: SCSI device returned error!\n"); - - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ | ATAPI_STAT_CHECK; - atapi_regs[ATAPI_REG_ERRFEAT] = 0x50; // sense key = ILLEGAL REQUEST - atapi_regs[ATAPI_REG_COUNTLOW] = 0; - atapi_regs[ATAPI_REG_COUNTHIGH] = 0; - } - } - } - } - else - { - reg = offset<<1; - switch(mem_mask) - { - case 0x000000ff: - break; - case 0x0000ff00: - reg+=1; - data >>= 8; - break; - } - if (reg==6) m_cur_drive = (data & 0x10) >> 4; - if (m_cur_drive==1) return; - atapi_regs[reg] = data; - //logerror("ATAPI: reg %d = %x (offset %x mask %x)\n", reg, data, offset, mem_mask); - - if (reg == ATAPI_REG_CMDSTATUS) - { - logerror("ATAPI command %x issued!\n", data); - switch (data) - { - case 0xa0: // PACKET - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ; - atapi_regs[ATAPI_REG_INTREASON] = ATAPI_INTREASON_COMMAND; - - m_atapi_data_ptr = 0; - m_atapi_data_len = 0; - - /* we have no data */ - m_atapi_xferlen = 0; - m_atapi_xfermod = 0; - - m_atapi_cdata_wait = 0; - break; - - case 0xa1: // IDENTIFY PACKET DEVICE - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_DRQ; - - m_atapi_data_ptr = 0; - m_atapi_data_len = 512; - - /* we have no data */ - m_atapi_xferlen = 0; - m_atapi_xfermod = 0; - - memset( atapi_data, 0, m_atapi_data_len ); - - atapi_data[ 0 ^ 1 ] = 0x85; // ATAPI device, cmd set 5 compliant, DRQ within 3 ms of PACKET command - atapi_data[ 1 ^ 1 ] = 0x80; // ATAPI device, removable media - - memset( &atapi_data[ 46 ], ' ', 8 ); - atapi_data[ 46 ^ 1 ] = '1'; - atapi_data[ 47 ^ 1 ] = '.'; - atapi_data[ 48 ^ 1 ] = '0'; - - memset( &atapi_data[ 54 ], ' ', 40 ); - atapi_data[ 54 ^ 1 ] = 'M'; - atapi_data[ 55 ^ 1 ] = 'A'; - atapi_data[ 56 ^ 1 ] = 'M'; - atapi_data[ 57 ^ 1 ] = 'E'; - atapi_data[ 58 ^ 1 ] = ' '; - atapi_data[ 59 ^ 1 ] = 'C'; - atapi_data[ 60 ^ 1 ] = 'o'; - atapi_data[ 61 ^ 1 ] = 'm'; - atapi_data[ 62 ^ 1 ] = 'p'; - atapi_data[ 63 ^ 1 ] = 'r'; - atapi_data[ 64 ^ 1 ] = 'e'; - atapi_data[ 65 ^ 1 ] = 's'; - atapi_data[ 66 ^ 1 ] = 's'; - atapi_data[ 67 ^ 1 ] = 'e'; - atapi_data[ 68 ^ 1 ] = 'd'; - atapi_data[ 69 ^ 1 ] = ' '; - atapi_data[ 70 ^ 1 ] = 'C'; - atapi_data[ 71 ^ 1 ] = 'D'; - atapi_data[ 72 ^ 1 ] = '-'; - atapi_data[ 73 ^ 1 ] = 'R'; - atapi_data[ 74 ^ 1 ] = 'O'; - atapi_data[ 75 ^ 1 ] = 'M'; - - atapi_data[ 98 ^ 1 ] = 0x06; // Word 49=Capabilities, IORDY may be disabled (bit_10), LBA Supported mandatory (bit_9) - atapi_data[ 99 ^ 1 ] = 0x00; - - atapi_regs[ATAPI_REG_COUNTLOW] = 0; - atapi_regs[ATAPI_REG_COUNTHIGH] = 2; - - atapi_irq(this, ASSERT_LINE); - break; - case 0xec: //IDENTIFY DEVICE - Must abort here and set for packet data - atapi_regs[ATAPI_REG_ERRFEAT] = ATAPI_ERRFEAT_ABRT; - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_CHECK; - - atapi_irq(this, ASSERT_LINE); - break; - case 0xef: // SET FEATURES - atapi_regs[ATAPI_REG_CMDSTATUS] = 0; - - m_atapi_data_ptr = 0; - m_atapi_data_len = 0; - - atapi_irq(this, ASSERT_LINE); - break; - - case 0x08: // ATAPI RESET - atapi_regs[ATAPI_REG_CMDSTATUS] = 0x00; - atapi_regs[ATAPI_REG_ERRFEAT] = 0x01; - atapi_regs[ATAPI_REG_INTREASON] = 0x01; // SECTOR_COUNT - atapi_regs[ATAPI_REG_SAMTAG] = 0x01; // SECTOR_NUMBER - atapi_regs[ATAPI_REG_COUNTLOW] = 0x14; // CYLINDER_LSB - atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb; // CYLINDER_MSB - atapi_regs[ATAPI_REG_DRIVESEL] &= 0xf0; // HEAD_NUMBER - - atapi_irq(this, ASSERT_LINE); - break; - default: - logerror("ATAPI: Unknown IDE command %x\n", data); - atapi_regs[ATAPI_REG_ERRFEAT] = ATAPI_ERRFEAT_ABRT; - atapi_regs[ATAPI_REG_CMDSTATUS] = ATAPI_STAT_CHECK; - - atapi_irq(this, ASSERT_LINE); - break; - } - } - } -} - -static MACHINE_CONFIG_FRAGMENT( ide ) - MCFG_DEVICE_ADD("cdrom", SCSICD, 0) -MACHINE_CONFIG_END - -static INPUT_PORTS_START( ide ) - PORT_START("DSW") - PORT_DIPNAME( 0x01, 0x00, "IDE Configuration") - PORT_DIPSETTING( 0x00, "Primary" ) - PORT_DIPSETTING( 0x01, "Secondary" ) -INPUT_PORTS_END - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -const device_type ISA16_IDE_CD = &device_creator; - -//------------------------------------------------- -// machine_config_additions - device-specific -// machine configurations -//------------------------------------------------- - -machine_config_constructor isa16_ide_cd_device::device_mconfig_additions() const -{ - return MACHINE_CONFIG_NAME( ide ); -} - -//------------------------------------------------- -// input_ports - device-specific input ports -//------------------------------------------------- - -ioport_constructor isa16_ide_cd_device::device_input_ports() const -{ - return INPUT_PORTS_NAME( ide ); -} - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// isa16_ide_cd_device - constructor -//------------------------------------------------- - -isa16_ide_cd_device::isa16_ide_cd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, ISA16_IDE_CD, "IDE CD Drive Adapter", tag, owner, clock, "isa_ide_cd", __FILE__), - device_isa16_card_interface( mconfig, *this ), - m_is_primary(true), - m_inserted_cdrom(NULL) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void isa16_ide_cd_device::device_start() -{ - set_isa_device(); - m_inserted_cdrom = subdevice("cdrom"); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void isa16_ide_cd_device::device_reset() -{ - m_is_primary = (ioport("DSW")->read() & 1) ? false : true; - if (m_is_primary) { - m_isa->install16_device(0x01f0, 0x01f7, 0, 0, read16_delegate(FUNC(isa16_ide_cd_device::atapi_r), this), write16_delegate(FUNC(isa16_ide_cd_device::atapi_w), this)); - //m_isa->install16_device(0x03f0, 0x03f7, 0, 0, read16_delegate(FUNC(isa16_ide_cd_device::atapi_status_r), this), write16_delegate(FUNC(isa16_ide_cd_device::atapi_cmd_w), this)); - } else { - m_isa->install16_device(0x0170, 0x0177, 0, 0, read16_delegate(FUNC(isa16_ide_cd_device::atapi_r), this), write16_delegate(FUNC(isa16_ide_cd_device::atapi_w), this)); - m_isa->install16_device(0x0370, 0x0377, 0, 0, read16_delegate(FUNC(isa16_ide_cd_device::atapi_status_r), this), write16_delegate(FUNC(isa16_ide_cd_device::atapi_cmd_w), this)); - } - m_cur_drive = 0; - m_atapi_regs[ATAPI_REG_CMDSTATUS] = 0x00; - m_atapi_regs[ATAPI_REG_ERRFEAT] = 0x01; - m_atapi_regs[ATAPI_REG_INTREASON] = 0x01; // SECTOR_COUNT - m_atapi_regs[ATAPI_REG_SAMTAG] = 0x01; // SECTOR_NUMBER - m_atapi_regs[ATAPI_REG_COUNTLOW] = 0x14; // CYLINDER_LSB - m_atapi_regs[ATAPI_REG_COUNTHIGH] = 0xeb; // CYLINDER_MSB - m_atapi_regs[ATAPI_REG_DRIVESEL] = 0xA0; // HEAD_NUMBER -} diff --git a/src/mess/machine/isa_ide_cd.h b/src/mess/machine/isa_ide_cd.h deleted file mode 100644 index d88ed2f80a1..00000000000 --- a/src/mess/machine/isa_ide_cd.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#ifndef __ISA_IDE_CD_H__ -#define __ISA_IDE_CD_H__ - -#include "emu.h" -#include "machine/isa.h" -#include "imagedev/chd_cd.h" -#include "machine/cr589.h" - -//************************************************************************** -// TYPE DEFINITIONS -//************************************************************************** -#define ATAPI_CYCLES_PER_SECTOR (5000) // plenty of time to allow DMA setup etc. BIOS requires this be at least 2000, individual games may vary. - -#define ATAPI_ERRFEAT_ABRT 0x04 - -#define ATAPI_STAT_BSY 0x80 -#define ATAPI_STAT_DRDY 0x40 -#define ATAPI_STAT_DMARDDF 0x20 -#define ATAPI_STAT_SERVDSC 0x10 -#define ATAPI_STAT_DRQ 0x08 -#define ATAPI_STAT_CORR 0x04 -#define ATAPI_STAT_CHECK 0x01 - -#define ATAPI_INTREASON_COMMAND 0x01 -#define ATAPI_INTREASON_IO 0x02 -#define ATAPI_INTREASON_RELEASE 0x04 - -#define ATAPI_REG_DATA 0 -#define ATAPI_REG_ERRFEAT 1 -#define ATAPI_REG_INTREASON 2 -#define ATAPI_REG_SAMTAG 3 -#define ATAPI_REG_COUNTLOW 4 -#define ATAPI_REG_COUNTHIGH 5 -#define ATAPI_REG_DRIVESEL 6 -#define ATAPI_REG_CMDSTATUS 7 -#define ATAPI_REG_MAX 16 - -#define ATAPI_DATA_SIZE ( 64 * 1024 ) - -#define MAX_TRANSFER_SIZE ( 63488 ) - -// ======================> isa16_ide_cd_device - -class isa16_ide_cd_device : - public device_t, - public device_isa16_card_interface -{ -public: - // construction/destruction - isa16_ide_cd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - // optional information overrides - virtual machine_config_constructor device_mconfig_additions() const; - virtual ioport_constructor device_input_ports() const; - - bool is_primary() { return m_is_primary; } - - - DECLARE_READ16_MEMBER(atapi_r); - DECLARE_WRITE16_MEMBER(atapi_w); - DECLARE_READ16_MEMBER(atapi_status_r); - DECLARE_WRITE16_MEMBER(atapi_cmd_w); -protected: - // device-level overrides - virtual void device_start(); - virtual void device_reset(); -private: - // internal state - bool m_is_primary; - - // CDROM - scsicd_device *m_inserted_cdrom; - - int m_atapi_data_ptr; - int m_atapi_data_len; - int m_atapi_xferlen; - int m_atapi_cdata_wait; - int m_atapi_xfermod; - /* memory */ - UINT8 m_atapi_regs[ATAPI_REG_MAX]; - UINT8 m_atapi_data[ATAPI_DATA_SIZE]; - - int m_cur_drive; -}; - - -// device type definition -extern const device_type ISA16_IDE_CD; - -#endif /* __ISA_IDE_CD_H__ */ diff --git a/src/mess/machine/southbridge.c b/src/mess/machine/southbridge.c index 918d8a4edd6..9bfb25e4022 100644 --- a/src/mess/machine/southbridge.c +++ b/src/mess/machine/southbridge.c @@ -99,8 +99,6 @@ static SLOT_INTERFACE_START(pc_isa_onboard) SLOT_INTERFACE("comat", ISA8_COM_AT) SLOT_INTERFACE("lpt", ISA8_LPT) SLOT_INTERFACE("fdcsmc", ISA8_FDC_SMC) - SLOT_INTERFACE("ide", ISA16_IDE) - SLOT_INTERFACE("ide_cd", ISA16_IDE_CD) SLOT_INTERFACE_END static MACHINE_CONFIG_FRAGMENT( southbridge ) @@ -116,7 +114,15 @@ static MACHINE_CONFIG_FRAGMENT( southbridge ) MCFG_PC_KBDC_ADD("pc_kbdc", pc_kbdc_intf) MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) - MCFG_MC146818_IRQ_ADD("rtc", MC146818_STANDARD, WRITELINE(southbridge_device, at_mc146818_irq)) + MCFG_MC146818_IRQ_ADD("rtc", MC146818_STANDARD, DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w)) + + MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", NULL, true) + MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w)) + MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) + + MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide2", ata_devices, "cdrom", NULL, true) + MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir7_w)) + MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -127,8 +133,7 @@ static MACHINE_CONFIG_FRAGMENT( southbridge ) // on board devices MCFG_ISA16_SLOT_ADD("isabus","board1", pc_isa_onboard, "fdcsmc", true) MCFG_ISA16_SLOT_ADD("isabus","board2", pc_isa_onboard, "comat", true) - MCFG_ISA16_SLOT_ADD("isabus","board3", pc_isa_onboard, "ide", true) - MCFG_ISA16_SLOT_ADD("isabus","board4", pc_isa_onboard, "lpt", true) + MCFG_ISA16_SLOT_ADD("isabus","board3", pc_isa_onboard, "lpt", true) MACHINE_CONFIG_END //------------------------------------------------- @@ -153,7 +158,9 @@ southbridge_device::southbridge_device(const machine_config &mconfig, device_typ m_isabus(*this, "isabus"), m_speaker(*this, "speaker"), m_mc146818(*this, "rtc"), - m_pc_kbdc(*this, "pc_kbdc") + m_pc_kbdc(*this, "pc_kbdc"), + m_ide(*this, "ide"), + m_ide2(*this, "ide2") { } /********************************************************** @@ -184,6 +191,10 @@ void southbridge_device::device_start() spaceio.install_readwrite_handler(0x0080, 0x009f, read8_delegate(FUNC(southbridge_device::at_page8_r),this), write8_delegate(FUNC(southbridge_device::at_page8_w),this), 0xffffffff); spaceio.install_readwrite_handler(0x00a0, 0x00bf, read8_delegate(FUNC(pic8259_device::read),&(*m_pic8259_slave)), write8_delegate(FUNC(pic8259_device::write),&(*m_pic8259_slave)), 0xffffffff); spaceio.install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(southbridge_device::at_dma8237_2_r),this), write8_delegate(FUNC(southbridge_device::at_dma8237_2_w),this), 0xffffffff); + spaceio.install_readwrite_handler(0x0170, 0x0177, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs0),&(*m_ide2)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs0), &(*m_ide2)),0xffffffff); + spaceio.install_readwrite_handler(0x01f0, 0x01f7, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs0),&(*m_ide)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs0), &(*m_ide)),0xffffffff); + spaceio.install_readwrite_handler(0x0370, 0x0377, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs1),&(*m_ide2)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs1), &(*m_ide2)),0xffffffff); + spaceio.install_readwrite_handler(0x03f0, 0x03f7, read32_delegate(FUNC(bus_master_ide_controller_device::read_cs1),&(*m_ide)), write32_delegate(FUNC(bus_master_ide_controller_device::write_cs1), &(*m_ide)),0xffffffff); spaceio.nop_readwrite(0x00e0, 0x00ef); @@ -440,11 +451,6 @@ WRITE8_MEMBER( southbridge_device::at_portb_w ) m_isabus->set_nmi_state((m_nmi_enabled==0) && (m_channel_check==0)); } -WRITE_LINE_MEMBER( southbridge_device::at_mc146818_irq ) -{ - m_pic8259_slave->ir0_w((state) ? 0 : 1); -} - READ8_MEMBER( southbridge_device::at_dma8237_2_r ) { return m_dma8237_2->read( space, offset / 2); diff --git a/src/mess/machine/southbridge.h b/src/mess/machine/southbridge.h index d98c92f6aea..28ba5561e81 100644 --- a/src/mess/machine/southbridge.h +++ b/src/mess/machine/southbridge.h @@ -63,6 +63,8 @@ public: required_device m_speaker; required_device m_mc146818; required_device m_pc_kbdc; + required_device m_ide; + required_device m_ide2; DECLARE_READ8_MEMBER(at_page8_r); DECLARE_WRITE8_MEMBER(at_page8_w); DECLARE_READ8_MEMBER(at_portb_r); @@ -100,7 +102,6 @@ public: DECLARE_WRITE8_MEMBER(at_dma8237_2_w); DECLARE_READ8_MEMBER(at_keybc_r); DECLARE_WRITE8_MEMBER(at_keybc_w); - DECLARE_WRITE_LINE_MEMBER(at_mc146818_irq); DECLARE_WRITE8_MEMBER(write_rtc); DECLARE_READ8_MEMBER(pc_dma_read_byte); DECLARE_WRITE8_MEMBER(pc_dma_write_byte); diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 1adc0b7fdd7..616f3f632d0 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -800,7 +800,6 @@ $(MESSOBJ)/isa.a: \ $(MESS_MACHINE)/isa_ssi2001.o \ $(MESS_MACHINE)/isa_ide.o \ $(MESS_MACHINE)/isa_ide8.o \ - $(MESS_MACHINE)/isa_ide_cd.o\ $(MESS_MACHINE)/isa_aha1542.o \ $(MESS_MACHINE)/isa_wd1002a_wx1.o\ $(MESS_VIDEO)/isa_cga.o \