mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Replaced ISA16_IDE_CD with ATAPI_CDROM, replaced ISA16_IDE & ISA16_IDE_CD in southbridge_device with two BUS_MASTER_IDE_CONTROLLERs. [smf]
This commit is contained in:
parent
bedef5a251
commit
62f3a522f6
8
.gitattributes
vendored
8
.gitattributes
vendored
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
754
src/emu/machine/atahle.c
Normal file
754
src/emu/machine/atahle.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
186
src/emu/machine/atahle.h
Normal file
186
src/emu/machine/atahle.h
Normal file
@ -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
|
@ -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) :
|
||||
|
71
src/emu/machine/atapicdr.c
Normal file
71
src/emu/machine/atapicdr.c
Normal file
@ -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::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;
|
||||
}
|
34
src/emu/machine/atapicdr.h
Normal file
34
src/emu/machine/atapicdr.h
Normal file
@ -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
|
198
src/emu/machine/atapihle.c
Normal file
198
src/emu/machine/atapihle.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
52
src/emu/machine/atapihle.h
Normal file
52
src/emu/machine/atapihle.h
Normal file
@ -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<scsihle_device> m_scsidev_device;
|
||||
|
||||
static const int ATAPI_BUFFER_LENGTH = 0x800;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -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<harddisk_image_device> m_image;
|
||||
|
||||
emu_timer * m_last_status_timer;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type IDE_HARDDISK;
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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<isa16_ide_cd_device *>(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<cpu_device *>(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<isa16_ide_cd_device>;
|
||||
|
||||
//-------------------------------------------------
|
||||
// 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<scsicd_device>("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
|
||||
}
|
@ -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__ */
|
@ -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);
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<mc146818_device> m_mc146818;
|
||||
required_device<pc_kbdc_device> m_pc_kbdc;
|
||||
required_device<bus_master_ide_controller_device> m_ide;
|
||||
required_device<bus_master_ide_controller_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);
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user