mirror of
https://github.com/holub/mame
synced 2025-04-27 02:33:13 +03:00
Uses one timer instead of anonymous timers, so that resetting the device will stop any outstanding work. BSY is always set when waiting for the busy timer to fire. Implemented DASP & PDIAG functionality, device 1 is detected during reset & if device 1 fails diagnostic then device 0 sets bit 7 of it's diagnostic result. Ide cards now default to 1 hard disk, otherwise device 1 without a chd will cause device 0 to report a controller error (AMIBIOS for example doesn't allow booting from device 0 if device 1 fails). Timing of DASP & PDIAG is set very short because of lack of wait states when accessing ATA bus. Improved SRST functionality, which has meant viper needed to be changed to trigger a hard reset instead of a soft reset. Writes to the command register are now ignored with BSY or DRQ is set (packet devices can accept the DEVICE RESET command but they are not supported yet). [smf]
This commit is contained in:
parent
f07afceb6b
commit
7c27ec1308
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
ata_device_interface::ata_device_interface(const machine_config &mconfig, device_t &device) :
|
ata_device_interface::ata_device_interface(const machine_config &mconfig, device_t &device) :
|
||||||
m_irq_handler(device),
|
m_irq_handler(device),
|
||||||
m_dmarq_handler(device)
|
m_dmarq_handler(device),
|
||||||
|
m_dasp_handler(device),
|
||||||
|
m_pdiag_handler(device)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -34,9 +34,12 @@ public:
|
|||||||
virtual DECLARE_WRITE_LINE_MEMBER(write_dmack) = 0;
|
virtual DECLARE_WRITE_LINE_MEMBER(write_dmack) = 0;
|
||||||
virtual DECLARE_WRITE_LINE_MEMBER(write_csel) = 0;
|
virtual DECLARE_WRITE_LINE_MEMBER(write_csel) = 0;
|
||||||
virtual DECLARE_WRITE_LINE_MEMBER(write_dasp) = 0;
|
virtual DECLARE_WRITE_LINE_MEMBER(write_dasp) = 0;
|
||||||
|
virtual DECLARE_WRITE_LINE_MEMBER(write_pdiag) = 0;
|
||||||
|
|
||||||
devcb2_write_line m_irq_handler;
|
devcb2_write_line m_irq_handler;
|
||||||
devcb2_write_line m_dmarq_handler;
|
devcb2_write_line m_dmarq_handler;
|
||||||
|
devcb2_write_line m_dasp_handler;
|
||||||
|
devcb2_write_line m_pdiag_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,24 +14,10 @@
|
|||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "idehd.h"
|
#include "idehd.h"
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
DEBUGGING
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#define VERBOSE 0
|
|
||||||
|
|
||||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
|
||||||
|
|
||||||
void ata_interface_device::set_irq(int state)
|
void ata_interface_device::set_irq(int state)
|
||||||
{
|
{
|
||||||
// printf( "irq %d\n", state );
|
// printf( "irq %d\n", state );
|
||||||
|
|
||||||
if (state == ASSERT_LINE)
|
|
||||||
LOG(("ATA interrupt assert\n"));
|
|
||||||
else
|
|
||||||
LOG(("ATA interrupt clear\n"));
|
|
||||||
|
|
||||||
/* signal an interrupt */
|
|
||||||
m_irq_handler(state);
|
m_irq_handler(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +28,13 @@ void ata_interface_device::set_dmarq(int state)
|
|||||||
m_dmarq_handler(state);
|
m_dmarq_handler(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ata_interface_device::set_dasp(int state)
|
||||||
|
{
|
||||||
|
// printf( "dasp %d\n", state );
|
||||||
|
|
||||||
|
m_dasp_handler(state);
|
||||||
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( ata_interface_device::irq0_write_line )
|
WRITE_LINE_MEMBER( ata_interface_device::irq0_write_line )
|
||||||
{
|
{
|
||||||
if (m_irq[0] != state)
|
if (m_irq[0] != state)
|
||||||
@ -62,6 +55,30 @@ WRITE_LINE_MEMBER( ata_interface_device::irq1_write_line )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER( ata_interface_device::dasp0_write_line )
|
||||||
|
{
|
||||||
|
if (m_dasp[0] != state)
|
||||||
|
{
|
||||||
|
m_dasp[0] = state;
|
||||||
|
|
||||||
|
set_dasp(m_dasp[0] == ASSERT_LINE || m_dasp[1] == ASSERT_LINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER( ata_interface_device::dasp1_write_line )
|
||||||
|
{
|
||||||
|
if (m_dasp[1] != state)
|
||||||
|
{
|
||||||
|
m_dasp[1] = state;
|
||||||
|
|
||||||
|
ata_device_interface *dev = m_slot[0]->dev();
|
||||||
|
if (dev != NULL)
|
||||||
|
dev->write_dasp(state);
|
||||||
|
|
||||||
|
set_dasp(m_dasp[0] == ASSERT_LINE || m_dasp[1] == ASSERT_LINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( ata_interface_device::dmarq0_write_line )
|
WRITE_LINE_MEMBER( ata_interface_device::dmarq0_write_line )
|
||||||
{
|
{
|
||||||
if (m_dmarq[0] != state)
|
if (m_dmarq[0] != state)
|
||||||
@ -82,6 +99,22 @@ WRITE_LINE_MEMBER( ata_interface_device::dmarq1_write_line )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER( ata_interface_device::pdiag0_write_line )
|
||||||
|
{
|
||||||
|
m_pdiag[0] = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_LINE_MEMBER( ata_interface_device::pdiag1_write_line )
|
||||||
|
{
|
||||||
|
if (m_pdiag[1] != state)
|
||||||
|
{
|
||||||
|
m_pdiag[1] = state;
|
||||||
|
|
||||||
|
ata_device_interface *dev = m_slot[0]->dev();
|
||||||
|
if (dev != NULL)
|
||||||
|
dev->write_pdiag(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
@ -174,8 +207,8 @@ 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) :
|
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) :
|
||||||
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||||
m_irq_handler(*this),
|
m_irq_handler(*this),
|
||||||
m_dmarq_handler(*this)
|
m_dmarq_handler(*this),
|
||||||
{
|
m_dasp_handler(*this){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -184,7 +217,8 @@ const device_type ATA_INTERFACE = &device_creator<ata_interface_device>;
|
|||||||
ata_interface_device::ata_interface_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
ata_interface_device::ata_interface_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||||
device_t(mconfig, ATA_INTERFACE, "ATA Interface", tag, owner, clock, "ata_interface", __FILE__),
|
device_t(mconfig, ATA_INTERFACE, "ATA Interface", tag, owner, clock, "ata_interface", __FILE__),
|
||||||
m_irq_handler(*this),
|
m_irq_handler(*this),
|
||||||
m_dmarq_handler(*this)
|
m_dmarq_handler(*this),
|
||||||
|
m_dasp_handler(*this)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +230,7 @@ void ata_interface_device::device_start()
|
|||||||
{
|
{
|
||||||
m_irq_handler.resolve_safe();
|
m_irq_handler.resolve_safe();
|
||||||
m_dmarq_handler.resolve_safe();
|
m_dmarq_handler.resolve_safe();
|
||||||
|
m_dasp_handler.resolve_safe();
|
||||||
|
|
||||||
/* set MAME harddisk handle */
|
/* set MAME harddisk handle */
|
||||||
m_slot[0] = subdevice<ata_slot_device>("0");
|
m_slot[0] = subdevice<ata_slot_device>("0");
|
||||||
@ -205,6 +240,8 @@ void ata_interface_device::device_start()
|
|||||||
{
|
{
|
||||||
m_irq[i] = 0;
|
m_irq[i] = 0;
|
||||||
m_dmarq[i] = 0;
|
m_dmarq[i] = 0;
|
||||||
|
m_dasp[i] = 0;
|
||||||
|
m_pdiag[i] = 0;
|
||||||
|
|
||||||
ata_device_interface *dev = m_slot[i]->dev();
|
ata_device_interface *dev = m_slot[i]->dev();
|
||||||
if (dev != NULL)
|
if (dev != NULL)
|
||||||
@ -213,30 +250,22 @@ void ata_interface_device::device_start()
|
|||||||
{
|
{
|
||||||
dev->m_irq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, irq0_write_line));
|
dev->m_irq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, irq0_write_line));
|
||||||
dev->m_dmarq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, dmarq0_write_line));
|
dev->m_dmarq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, dmarq0_write_line));
|
||||||
|
dev->m_dasp_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, dasp0_write_line));
|
||||||
|
dev->m_pdiag_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, pdiag0_write_line));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dev->m_irq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, irq1_write_line));
|
dev->m_irq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, irq1_write_line));
|
||||||
dev->m_dmarq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, dmarq1_write_line));
|
dev->m_dmarq_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, dmarq1_write_line));
|
||||||
|
dev->m_dasp_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, dasp1_write_line));
|
||||||
|
dev->m_pdiag_handler.set_callback(DEVCB2_DEVWRITELINE("^", ata_interface_device, pdiag1_write_line));
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->write_csel(i);
|
dev->write_csel(i);
|
||||||
dev->write_dasp(m_slot[1]->dev() != NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// device_reset - device-specific reset
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void ata_interface_device::device_reset()
|
|
||||||
{
|
|
||||||
LOG(("ATA interface reset\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// ATA SLOT DEVICE
|
// ATA SLOT DEVICE
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
@ -51,6 +51,9 @@ extern const device_type ATA_SLOT;
|
|||||||
#define MCFG_ATA_INTERFACE_DMARQ_HANDLER(_devcb) \
|
#define MCFG_ATA_INTERFACE_DMARQ_HANDLER(_devcb) \
|
||||||
devcb = &ata_interface_device::set_dmarq_handler(*device, DEVCB2_##_devcb);
|
devcb = &ata_interface_device::set_dmarq_handler(*device, DEVCB2_##_devcb);
|
||||||
|
|
||||||
|
#define MCFG_ATA_INTERFACE_DASP_HANDLER(_devcb) \
|
||||||
|
devcb = &ata_interface_device::set_dasp_handler(*device, DEVCB2_##_devcb);
|
||||||
|
|
||||||
SLOT_INTERFACE_EXTERN(ata_devices);
|
SLOT_INTERFACE_EXTERN(ata_devices);
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -82,7 +85,7 @@ public:
|
|||||||
// static configuration helpers
|
// static configuration helpers
|
||||||
template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<ata_interface_device &>(device).m_irq_handler.set_callback(object); }
|
template<class _Object> static devcb2_base &set_irq_handler(device_t &device, _Object object) { return downcast<ata_interface_device &>(device).m_irq_handler.set_callback(object); }
|
||||||
template<class _Object> static devcb2_base &set_dmarq_handler(device_t &device, _Object object) { return downcast<ata_interface_device &>(device).m_dmarq_handler.set_callback(object); }
|
template<class _Object> static devcb2_base &set_dmarq_handler(device_t &device, _Object object) { return downcast<ata_interface_device &>(device).m_dmarq_handler.set_callback(object); }
|
||||||
|
template<class _Object> static devcb2_base &set_dasp_handler(device_t &device, _Object object) { return downcast<ata_interface_device &>(device).m_dasp_handler.set_callback(object); }
|
||||||
UINT16 read_dma();
|
UINT16 read_dma();
|
||||||
virtual DECLARE_READ16_MEMBER(read_cs0);
|
virtual DECLARE_READ16_MEMBER(read_cs0);
|
||||||
virtual DECLARE_READ16_MEMBER(read_cs1);
|
virtual DECLARE_READ16_MEMBER(read_cs1);
|
||||||
@ -95,24 +98,31 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start();
|
virtual void device_start();
|
||||||
virtual void device_reset();
|
|
||||||
|
|
||||||
virtual void set_irq(int state);
|
virtual void set_irq(int state);
|
||||||
virtual void set_dmarq(int state);
|
virtual void set_dmarq(int state);
|
||||||
|
virtual void set_dasp(int state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_WRITE_LINE_MEMBER(irq0_write_line);
|
DECLARE_WRITE_LINE_MEMBER(irq0_write_line);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dmarq0_write_line);
|
DECLARE_WRITE_LINE_MEMBER(dmarq0_write_line);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(dasp0_write_line);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(pdiag0_write_line);
|
||||||
|
|
||||||
DECLARE_WRITE_LINE_MEMBER(irq1_write_line);
|
DECLARE_WRITE_LINE_MEMBER(irq1_write_line);
|
||||||
DECLARE_WRITE_LINE_MEMBER(dmarq1_write_line);
|
DECLARE_WRITE_LINE_MEMBER(dmarq1_write_line);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(dasp1_write_line);
|
||||||
|
DECLARE_WRITE_LINE_MEMBER(pdiag1_write_line);
|
||||||
|
|
||||||
ata_slot_device *m_slot[2];
|
ata_slot_device *m_slot[2];
|
||||||
int m_irq[2];
|
int m_irq[2];
|
||||||
int m_dmarq[2];
|
int m_dmarq[2];
|
||||||
|
int m_dasp[2];
|
||||||
|
int m_pdiag[2];
|
||||||
|
|
||||||
devcb2_write_line m_irq_handler;
|
devcb2_write_line m_irq_handler;
|
||||||
devcb2_write_line m_dmarq_handler;
|
devcb2_write_line m_dmarq_handler;
|
||||||
|
devcb2_write_line m_dasp_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const device_type ATA_INTERFACE;
|
extern const device_type ATA_INTERFACE;
|
||||||
|
@ -16,10 +16,15 @@
|
|||||||
|
|
||||||
#define TIME_PER_SECTOR (attotime::from_usec(100))
|
#define TIME_PER_SECTOR (attotime::from_usec(100))
|
||||||
#define TIME_PER_ROTATION (attotime::from_hz(5400/60))
|
#define TIME_PER_ROTATION (attotime::from_hz(5400/60))
|
||||||
|
#define TIME_MULTIPLE_SECTORS (attotime::from_usec(1))
|
||||||
|
|
||||||
#define TIME_SEEK_MULTISECTOR (attotime::from_msec(13))
|
#define TIME_SEEK_MULTISECTOR (attotime::from_msec(13))
|
||||||
#define TIME_NO_SEEK_MULTISECTOR (attotime::from_nsec(16300))
|
#define TIME_NO_SEEK_MULTISECTOR (attotime::from_nsec(16300))
|
||||||
|
|
||||||
|
#define 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_DATA_RW 0
|
||||||
#define IDE_CS0_ERROR_R 1
|
#define IDE_CS0_ERROR_R 1
|
||||||
#define IDE_CS0_FEATURE_W 1
|
#define IDE_CS0_FEATURE_W 1
|
||||||
@ -63,11 +68,16 @@
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TID_NULL,
|
TID_NULL,
|
||||||
TID_DELAYED_INTERRUPT,
|
TID_BUSY,
|
||||||
TID_DELAYED_INTERRUPT_BUFFER_READY,
|
};
|
||||||
TID_RESET_CALLBACK,
|
|
||||||
TID_READ_SECTOR_DONE_CALLBACK,
|
enum
|
||||||
TID_WRITE_SECTOR_DONE_CALLBACK
|
{
|
||||||
|
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)
|
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)
|
||||||
@ -76,10 +86,13 @@ ata_mass_storage_device::ata_mass_storage_device(const machine_config &mconfig,
|
|||||||
device_slot_card_interface(mconfig, *this),
|
device_slot_card_interface(mconfig, *this),
|
||||||
m_can_identify_device(0),
|
m_can_identify_device(0),
|
||||||
m_csel(0),
|
m_csel(0),
|
||||||
m_dasp(0),
|
m_daspin(0),
|
||||||
|
m_daspout(0),
|
||||||
m_dmack(0),
|
m_dmack(0),
|
||||||
m_dmarq(0),
|
m_dmarq(0),
|
||||||
m_irq(0),
|
m_irq(0),
|
||||||
|
m_pdiagin(0),
|
||||||
|
m_pdiagout(0),
|
||||||
m_master_password(NULL),
|
m_master_password(NULL),
|
||||||
m_user_password(NULL)
|
m_user_password(NULL)
|
||||||
{
|
{
|
||||||
@ -118,6 +131,26 @@ void ata_mass_storage_device::set_dmarq(int 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 )
|
WRITE_LINE_MEMBER( ata_mass_storage_device::write_csel )
|
||||||
{
|
{
|
||||||
m_csel = state;
|
m_csel = state;
|
||||||
@ -125,7 +158,7 @@ WRITE_LINE_MEMBER( ata_mass_storage_device::write_csel )
|
|||||||
|
|
||||||
WRITE_LINE_MEMBER( ata_mass_storage_device::write_dasp )
|
WRITE_LINE_MEMBER( ata_mass_storage_device::write_dasp )
|
||||||
{
|
{
|
||||||
m_dasp = state;
|
m_daspin = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE_LINE_MEMBER( ata_mass_storage_device::write_dmack )
|
WRITE_LINE_MEMBER( ata_mass_storage_device::write_dmack )
|
||||||
@ -133,6 +166,17 @@ WRITE_LINE_MEMBER( ata_mass_storage_device::write_dmack )
|
|||||||
m_dmack = state;
|
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
|
* Compute the LBA address
|
||||||
@ -334,6 +378,8 @@ void ata_mass_storage_device::device_start()
|
|||||||
{
|
{
|
||||||
m_irq_handler.resolve_safe();
|
m_irq_handler.resolve_safe();
|
||||||
m_dmarq_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));
|
||||||
save_item(NAME(m_buffer_offset));
|
save_item(NAME(m_buffer_offset));
|
||||||
@ -360,10 +406,33 @@ void ata_mass_storage_device::device_start()
|
|||||||
|
|
||||||
/* create a timer for timing status */
|
/* create a timer for timing status */
|
||||||
m_last_status_timer = timer_alloc(TID_NULL);
|
m_last_status_timer = timer_alloc(TID_NULL);
|
||||||
m_reset_timer = timer_alloc(TID_RESET_CALLBACK);
|
m_busy_timer = timer_alloc(TID_BUSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ata_mass_storage_device::device_reset()
|
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;
|
m_buffer_offset = 0;
|
||||||
m_master_password_enable = (m_master_password != NULL);
|
m_master_password_enable = (m_master_password != NULL);
|
||||||
@ -376,50 +445,139 @@ void ata_mass_storage_device::device_reset()
|
|||||||
m_status |= IDE_STATUS_DRDY;
|
m_status |= IDE_STATUS_DRDY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start_busy(DIAGNOSTIC_TIME, PARAM_DIAGNOSTIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ata_mass_storage_device::perform_diagnostic()
|
||||||
|
{
|
||||||
if (m_can_identify_device)
|
if (m_can_identify_device)
|
||||||
|
{
|
||||||
m_error = IDE_ERROR_DIAGNOSTIC_PASSED;
|
m_error = IDE_ERROR_DIAGNOSTIC_PASSED;
|
||||||
|
|
||||||
|
if (m_csel == 1)
|
||||||
|
set_pdiag(ASSERT_LINE);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
m_error = IDE_ERROR_DIAGNOSTIC_FAILED;
|
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()
|
||||||
|
{
|
||||||
m_sector_count = 1;
|
m_sector_count = 1;
|
||||||
m_sector_number = 1;
|
m_sector_number = 1;
|
||||||
m_cylinder_low = 0;
|
m_cylinder_low = 0;
|
||||||
m_cylinder_high = 0;
|
m_cylinder_high = 0;
|
||||||
m_device_head = 0;
|
m_device_head = 0;
|
||||||
|
|
||||||
/* reset the drive state */
|
m_resetting = false;
|
||||||
set_irq(CLEAR_LINE);
|
}
|
||||||
set_dmarq(CLEAR_LINE);
|
|
||||||
|
|
||||||
|
void ata_mass_storage_device::start_busy(attotime time, int param)
|
||||||
|
{
|
||||||
|
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)
|
void ata_mass_storage_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
switch(id)
|
switch(id)
|
||||||
{
|
{
|
||||||
case TID_DELAYED_INTERRUPT:
|
case TID_BUSY:
|
||||||
m_status &= ~IDE_STATUS_BSY;
|
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_DIAGNOSTIC:
|
||||||
|
perform_diagnostic();
|
||||||
|
|
||||||
|
if (m_csel == 0)
|
||||||
set_irq(ASSERT_LINE);
|
set_irq(ASSERT_LINE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TID_DELAYED_INTERRUPT_BUFFER_READY:
|
case IDE_COMMAND_IDENTIFY_DEVICE:
|
||||||
m_status &= ~IDE_STATUS_BSY;
|
if (m_can_identify_device)
|
||||||
|
{
|
||||||
|
memcpy(m_buffer, m_identify_device, sizeof(m_buffer));
|
||||||
m_status |= IDE_STATUS_DRQ;
|
m_status |= IDE_STATUS_DRQ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_status |= IDE_STATUS_ERR;
|
||||||
|
m_error = IDE_ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
set_irq(ASSERT_LINE);
|
set_irq(ASSERT_LINE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TID_RESET_CALLBACK:
|
case IDE_COMMAND_SET_CONFIG:
|
||||||
reset();
|
set_geometry(m_sector_count,(m_device_head & IDE_DEVICE_HEAD_HS) + 1);
|
||||||
|
set_irq(ASSERT_LINE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TID_READ_SECTOR_DONE_CALLBACK:
|
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();
|
read_sector_done();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TID_WRITE_SECTOR_DONE_CALLBACK:
|
case IDE_COMMAND_WRITE_SECTORS:
|
||||||
|
case IDE_COMMAND_WRITE_SECTORS_NORETRY:
|
||||||
|
case IDE_COMMAND_WRITE_MULTIPLE:
|
||||||
|
case IDE_COMMAND_WRITE_DMA:
|
||||||
write_sector_done();
|
write_sector_done();
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,7 +697,7 @@ void ata_mass_storage_device::read_sector_done()
|
|||||||
{
|
{
|
||||||
int lba = lba_address(), count = 0;
|
int lba = lba_address(), count = 0;
|
||||||
|
|
||||||
m_status &= ~IDE_STATUS_BSY;
|
set_dasp(CLEAR_LINE);
|
||||||
|
|
||||||
/* now do the read */
|
/* now do the read */
|
||||||
count = read_sector(lba, m_buffer);
|
count = read_sector(lba, m_buffer);
|
||||||
@ -589,8 +747,7 @@ void ata_mass_storage_device::read_sector_done()
|
|||||||
|
|
||||||
void ata_mass_storage_device::read_first_sector()
|
void ata_mass_storage_device::read_first_sector()
|
||||||
{
|
{
|
||||||
/* mark ourselves busy */
|
set_dasp(ASSERT_LINE);
|
||||||
m_status |= IDE_STATUS_BSY;
|
|
||||||
|
|
||||||
/* just set a timer */
|
/* just set a timer */
|
||||||
if (m_command == IDE_COMMAND_READ_MULTIPLE)
|
if (m_command == IDE_COMMAND_READ_MULTIPLE)
|
||||||
@ -599,22 +756,20 @@ void ata_mass_storage_device::read_first_sector()
|
|||||||
attotime seek_time;
|
attotime seek_time;
|
||||||
|
|
||||||
if (new_lba == m_cur_lba || new_lba == m_cur_lba + 1)
|
if (new_lba == m_cur_lba || new_lba == m_cur_lba + 1)
|
||||||
seek_time = TIME_NO_SEEK_MULTISECTOR;
|
start_busy(TIME_NO_SEEK_MULTISECTOR, PARAM_COMMAND);
|
||||||
else
|
else
|
||||||
seek_time = TIME_SEEK_MULTISECTOR;
|
start_busy(TIME_SEEK_MULTISECTOR, PARAM_COMMAND);
|
||||||
|
|
||||||
m_cur_lba = new_lba;
|
m_cur_lba = new_lba;
|
||||||
timer_set(seek_time, TID_READ_SECTOR_DONE_CALLBACK);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
timer_set(TIME_PER_SECTOR, TID_READ_SECTOR_DONE_CALLBACK);
|
start_busy(TIME_PER_SECTOR, PARAM_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ata_mass_storage_device::read_next_sector()
|
void ata_mass_storage_device::read_next_sector()
|
||||||
{
|
{
|
||||||
/* mark ourselves busy */
|
set_dasp(ASSERT_LINE);
|
||||||
m_status |= IDE_STATUS_BSY;
|
|
||||||
|
|
||||||
if (m_command == IDE_COMMAND_READ_MULTIPLE)
|
if (m_command == IDE_COMMAND_READ_MULTIPLE)
|
||||||
{
|
{
|
||||||
@ -622,12 +777,10 @@ void ata_mass_storage_device::read_next_sector()
|
|||||||
/* make ready now */
|
/* make ready now */
|
||||||
read_sector_done();
|
read_sector_done();
|
||||||
else
|
else
|
||||||
/* just set a timer */
|
start_busy(TIME_MULTIPLE_SECTORS, PARAM_COMMAND);
|
||||||
timer_set(attotime::from_usec(1), TID_READ_SECTOR_DONE_CALLBACK);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* just set a timer */
|
start_busy(TIME_PER_SECTOR, PARAM_COMMAND);
|
||||||
timer_set(TIME_PER_SECTOR, TID_READ_SECTOR_DONE_CALLBACK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -643,8 +796,7 @@ void ata_mass_storage_device::continue_write()
|
|||||||
/* reset the totals */
|
/* reset the totals */
|
||||||
m_buffer_offset = 0;
|
m_buffer_offset = 0;
|
||||||
|
|
||||||
/* clear the buffer ready flag */
|
set_dasp(ASSERT_LINE);
|
||||||
m_status |= IDE_STATUS_BSY;
|
|
||||||
|
|
||||||
if (m_command == IDE_COMMAND_WRITE_MULTIPLE)
|
if (m_command == IDE_COMMAND_WRITE_MULTIPLE)
|
||||||
{
|
{
|
||||||
@ -656,13 +808,13 @@ void ata_mass_storage_device::continue_write()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* set a timer to do the write */
|
/* set a timer to do the write */
|
||||||
timer_set(TIME_PER_SECTOR, TID_WRITE_SECTOR_DONE_CALLBACK);
|
start_busy(TIME_PER_SECTOR, PARAM_COMMAND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* set a timer to do the write */
|
/* set a timer to do the write */
|
||||||
timer_set(TIME_PER_SECTOR, TID_WRITE_SECTOR_DONE_CALLBACK);
|
start_busy(TIME_PER_SECTOR, PARAM_COMMAND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,7 +870,7 @@ void ata_mass_storage_device::write_sector_done()
|
|||||||
{
|
{
|
||||||
int lba = lba_address(), count = 0;
|
int lba = lba_address(), count = 0;
|
||||||
|
|
||||||
m_status &= ~IDE_STATUS_BSY;
|
set_dasp(CLEAR_LINE);
|
||||||
|
|
||||||
/* now do the write */
|
/* now do the write */
|
||||||
count = write_sector(lba, m_buffer);
|
count = write_sector(lba, m_buffer);
|
||||||
@ -867,34 +1019,15 @@ bool ata_mass_storage_device::process_command()
|
|||||||
case IDE_COMMAND_IDENTIFY_DEVICE:
|
case IDE_COMMAND_IDENTIFY_DEVICE:
|
||||||
LOGPRINT(("IDE Identify device\n"));
|
LOGPRINT(("IDE Identify device\n"));
|
||||||
|
|
||||||
m_status |= IDE_STATUS_BSY;
|
start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND);
|
||||||
if (m_can_identify_device)
|
|
||||||
{
|
|
||||||
memcpy(m_buffer, m_identify_device, sizeof(m_buffer));
|
|
||||||
|
|
||||||
timer_set(MINIMUM_COMMAND_TIME, TID_DELAYED_INTERRUPT_BUFFER_READY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_status |= IDE_STATUS_ERR;
|
|
||||||
m_error = IDE_ERROR_NONE;
|
|
||||||
timer_set(MINIMUM_COMMAND_TIME, TID_DELAYED_INTERRUPT);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case IDE_COMMAND_DIAGNOSTIC:
|
case IDE_COMMAND_DIAGNOSTIC:
|
||||||
if (m_can_identify_device)
|
start_busy(DIAGNOSTIC_TIME, PARAM_COMMAND);
|
||||||
m_error = IDE_ERROR_DIAGNOSTIC_PASSED;
|
|
||||||
else
|
|
||||||
m_error = IDE_ERROR_DIAGNOSTIC_FAILED;
|
|
||||||
|
|
||||||
m_status |= IDE_STATUS_BSY;
|
|
||||||
timer_set(MINIMUM_COMMAND_TIME, TID_DELAYED_INTERRUPT);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case IDE_COMMAND_RECALIBRATE:
|
case IDE_COMMAND_RECALIBRATE:
|
||||||
m_status |= IDE_STATUS_BSY;
|
start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND);
|
||||||
timer_set(MINIMUM_COMMAND_TIME, TID_DELAYED_INTERRUPT);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case IDE_COMMAND_IDLE:
|
case IDE_COMMAND_IDLE:
|
||||||
@ -904,10 +1037,8 @@ bool ata_mass_storage_device::process_command()
|
|||||||
|
|
||||||
case IDE_COMMAND_SET_CONFIG:
|
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));
|
LOGPRINT(("IDE Set configuration (%d heads, %d sectors)\n", (m_device_head & IDE_DEVICE_HEAD_HS) + 1, m_sector_count));
|
||||||
set_geometry(m_sector_count,(m_device_head & IDE_DEVICE_HEAD_HS) + 1);
|
|
||||||
|
|
||||||
m_status |= IDE_STATUS_BSY;
|
start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND);
|
||||||
timer_set(MINIMUM_COMMAND_TIME, TID_DELAYED_INTERRUPT);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case IDE_COMMAND_SET_MAX:
|
case IDE_COMMAND_SET_MAX:
|
||||||
@ -920,8 +1051,7 @@ bool ata_mass_storage_device::process_command()
|
|||||||
case IDE_COMMAND_SET_FEATURES:
|
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));
|
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));
|
||||||
|
|
||||||
m_status |= IDE_STATUS_BSY;
|
start_busy(MINIMUM_COMMAND_TIME, PARAM_COMMAND);
|
||||||
timer_set(MINIMUM_COMMAND_TIME, TID_DELAYED_INTERRUPT);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case IDE_COMMAND_SET_BLOCK_COUNT:
|
case IDE_COMMAND_SET_BLOCK_COUNT:
|
||||||
@ -989,7 +1119,7 @@ READ16_MEMBER( ata_mass_storage_device::read_cs0 )
|
|||||||
|
|
||||||
UINT16 result = 0xffff;
|
UINT16 result = 0xffff;
|
||||||
|
|
||||||
if (device_selected() || single_device())
|
if (device_selected() || m_single_device)
|
||||||
{
|
{
|
||||||
if (m_dmack)
|
if (m_dmack)
|
||||||
{
|
{
|
||||||
@ -997,6 +1127,8 @@ READ16_MEMBER( ata_mass_storage_device::read_cs0 )
|
|||||||
}
|
}
|
||||||
else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_STATUS_R)
|
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())
|
if (device_selected())
|
||||||
{
|
{
|
||||||
switch (offset)
|
switch (offset)
|
||||||
@ -1093,9 +1225,7 @@ READ16_MEMBER( ata_mass_storage_device::read_cs0 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(m_status & IDE_STATUS_DRDY) && is_ready())
|
if (!(m_status & IDE_STATUS_DRDY) && is_ready())
|
||||||
{
|
|
||||||
m_status |= IDE_STATUS_DRDY;
|
m_status |= IDE_STATUS_DRDY;
|
||||||
}
|
|
||||||
|
|
||||||
set_irq(CLEAR_LINE);
|
set_irq(CLEAR_LINE);
|
||||||
}
|
}
|
||||||
@ -1125,7 +1255,7 @@ READ16_MEMBER( ata_mass_storage_device::read_cs1 )
|
|||||||
|
|
||||||
UINT16 result = 0xffff;
|
UINT16 result = 0xffff;
|
||||||
|
|
||||||
if (device_selected() || single_device())
|
if (device_selected() || m_single_device)
|
||||||
{
|
{
|
||||||
if (m_dmack)
|
if (m_dmack)
|
||||||
{
|
{
|
||||||
@ -1212,7 +1342,7 @@ WRITE16_MEMBER( ata_mass_storage_device::write_cs0 )
|
|||||||
}
|
}
|
||||||
else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_COMMAND_W)
|
else if ((m_status & IDE_STATUS_BSY) && offset != IDE_CS0_COMMAND_W)
|
||||||
{
|
{
|
||||||
logerror( "%s: dev %d write_cs0 %04x %04x %04x ignored (BSY)\n", machine().describe_context(), dev(), offset, data, mem_mask );
|
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)
|
else if ((m_status & IDE_STATUS_DRQ) && offset != IDE_CS0_DATA_RW && offset != IDE_CS0_COMMAND_W)
|
||||||
{
|
{
|
||||||
@ -1284,10 +1414,19 @@ WRITE16_MEMBER( ata_mass_storage_device::write_cs0 )
|
|||||||
|
|
||||||
/* command */
|
/* command */
|
||||||
case IDE_CS0_COMMAND_W:
|
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;
|
m_command = data;
|
||||||
|
|
||||||
if (device_selected() || m_command == IDE_COMMAND_DIAGNOSTIC)
|
|
||||||
{
|
|
||||||
/* implicitly clear interrupts & dmarq here */
|
/* implicitly clear interrupts & dmarq here */
|
||||||
set_irq(CLEAR_LINE);
|
set_irq(CLEAR_LINE);
|
||||||
set_dmarq(CLEAR_LINE);
|
set_dmarq(CLEAR_LINE);
|
||||||
@ -1295,7 +1434,7 @@ WRITE16_MEMBER( ata_mass_storage_device::write_cs0 )
|
|||||||
m_buffer_offset = 0;
|
m_buffer_offset = 0;
|
||||||
m_sectors_until_int = 0;
|
m_sectors_until_int = 0;
|
||||||
|
|
||||||
m_status &= ~IDE_STATUS_BSY;
|
set_dasp(CLEAR_LINE);
|
||||||
m_status &= ~IDE_STATUS_DRQ;
|
m_status &= ~IDE_STATUS_DRQ;
|
||||||
m_status &= ~IDE_STATUS_ERR;
|
m_status &= ~IDE_STATUS_ERR;
|
||||||
|
|
||||||
@ -1344,9 +1483,23 @@ WRITE16_MEMBER( ata_mass_storage_device::write_cs1 )
|
|||||||
{
|
{
|
||||||
if (m_device_control & IDE_DEVICE_CONTROL_SRST)
|
if (m_device_control & IDE_DEVICE_CONTROL_SRST)
|
||||||
{
|
{
|
||||||
m_status |= IDE_STATUS_BSY;
|
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_irq(CLEAR_LINE);
|
||||||
m_reset_timer->adjust(attotime::from_msec(5));
|
set_pdiag(CLEAR_LINE);
|
||||||
|
|
||||||
|
start_busy(attotime::never, PARAM_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_busy_timer->param() == PARAM_RESET)
|
||||||
|
{
|
||||||
|
soft_reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -61,6 +61,7 @@ public:
|
|||||||
virtual DECLARE_WRITE_LINE_MEMBER(write_csel);
|
virtual DECLARE_WRITE_LINE_MEMBER(write_csel);
|
||||||
virtual DECLARE_WRITE_LINE_MEMBER(write_dasp);
|
virtual DECLARE_WRITE_LINE_MEMBER(write_dasp);
|
||||||
virtual DECLARE_WRITE_LINE_MEMBER(write_dmack);
|
virtual DECLARE_WRITE_LINE_MEMBER(write_dmack);
|
||||||
|
virtual DECLARE_WRITE_LINE_MEMBER(write_pdiag);
|
||||||
|
|
||||||
UINT8 *identify_device_buffer() { return m_identify_device; }
|
UINT8 *identify_device_buffer() { return m_identify_device; }
|
||||||
|
|
||||||
@ -88,15 +89,17 @@ protected:
|
|||||||
|
|
||||||
int dev() { return (m_device_head & IDE_DEVICE_HEAD_DRV) >> 4; }
|
int dev() { return (m_device_head & IDE_DEVICE_HEAD_DRV) >> 4; }
|
||||||
bool device_selected() { return m_csel == dev(); }
|
bool device_selected() { return m_csel == dev(); }
|
||||||
bool single_device() { return m_csel == 0 && m_dasp == 0; }
|
|
||||||
|
|
||||||
void set_irq(int state);
|
void set_irq(int state);
|
||||||
void set_dmarq(int state);
|
void set_dmarq(int state);
|
||||||
|
void set_dasp(int state);
|
||||||
|
void set_pdiag(int state);
|
||||||
void ide_build_identify_device();
|
void ide_build_identify_device();
|
||||||
|
|
||||||
virtual bool process_command();
|
virtual bool process_command();
|
||||||
virtual void process_buffer();
|
virtual void process_buffer();
|
||||||
virtual void fill_buffer();
|
virtual void fill_buffer();
|
||||||
|
virtual void finished_busy(int param);
|
||||||
|
|
||||||
UINT8 m_buffer[IDE_DISK_SECTOR_SIZE];
|
UINT8 m_buffer[IDE_DISK_SECTOR_SIZE];
|
||||||
UINT16 m_buffer_offset;
|
UINT16 m_buffer_offset;
|
||||||
@ -131,12 +134,23 @@ private:
|
|||||||
void read_buffer_empty();
|
void read_buffer_empty();
|
||||||
void write_buffer_full();
|
void write_buffer_full();
|
||||||
void update_irq();
|
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_csel;
|
||||||
int m_dasp;
|
int m_daspin;
|
||||||
|
int m_daspout;
|
||||||
int m_dmack;
|
int m_dmack;
|
||||||
int m_dmarq;
|
int m_dmarq;
|
||||||
int m_irq;
|
int m_irq;
|
||||||
|
int m_pdiagin;
|
||||||
|
int m_pdiagout;
|
||||||
|
|
||||||
|
bool m_resetting;
|
||||||
|
bool m_single_device;
|
||||||
|
|
||||||
UINT32 m_cur_lba;
|
UINT32 m_cur_lba;
|
||||||
UINT16 m_block_count;
|
UINT16 m_block_count;
|
||||||
@ -148,7 +162,7 @@ private:
|
|||||||
const UINT8 * m_user_password;
|
const UINT8 * m_user_password;
|
||||||
|
|
||||||
emu_timer * m_last_status_timer;
|
emu_timer * m_last_status_timer;
|
||||||
emu_timer * m_reset_timer;
|
emu_timer * m_busy_timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ======================> ide_hdd_device
|
// ======================> ide_hdd_device
|
||||||
|
@ -1419,8 +1419,7 @@ WRITE64_MEMBER(viper_state::cf_card_w)
|
|||||||
{
|
{
|
||||||
m_cf_card_ide = 1;
|
m_cf_card_ide = 1;
|
||||||
|
|
||||||
// soft reset
|
m_ata->reset();
|
||||||
m_ata->write_cs1(space, 6, 0x04, 0xff);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ const device_type A2BUS_CFFA2_6502 = &device_creator<a2bus_cffa2_6502_device>;
|
|||||||
#define CFFA2_ATA_TAG "cffa2_ata"
|
#define CFFA2_ATA_TAG "cffa2_ata"
|
||||||
|
|
||||||
MACHINE_CONFIG_FRAGMENT( cffa2 )
|
MACHINE_CONFIG_FRAGMENT( cffa2 )
|
||||||
MCFG_ATA_INTERFACE_ADD(CFFA2_ATA_TAG, ata_devices, "hdd", "hdd", false)
|
MCFG_ATA_INTERFACE_ADD(CFFA2_ATA_TAG, ata_devices, "hdd", NULL, false)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
ROM_START( cffa2 )
|
ROM_START( cffa2 )
|
||||||
|
@ -66,7 +66,7 @@ const device_type A2BUS_VULCAN = &device_creator<a2bus_vulcan_device>;
|
|||||||
#define VULCAN_ATA_TAG "vulcan_ata"
|
#define VULCAN_ATA_TAG "vulcan_ata"
|
||||||
|
|
||||||
static MACHINE_CONFIG_FRAGMENT( vulcan )
|
static MACHINE_CONFIG_FRAGMENT( vulcan )
|
||||||
MCFG_ATA_INTERFACE_ADD(VULCAN_ATA_TAG, ata_devices, "hdd", "hdd", false)
|
MCFG_ATA_INTERFACE_ADD(VULCAN_ATA_TAG, ata_devices, "hdd", NULL, false)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
ROM_START( vulcan )
|
ROM_START( vulcan )
|
||||||
|
@ -32,7 +32,7 @@ const device_type A2BUS_ZIPDRIVE = &device_creator<a2bus_zipdrive_device>;
|
|||||||
#define ZIPDRIVE_ATA_TAG "zipdrive_ata"
|
#define ZIPDRIVE_ATA_TAG "zipdrive_ata"
|
||||||
|
|
||||||
static MACHINE_CONFIG_FRAGMENT( zipdrive )
|
static MACHINE_CONFIG_FRAGMENT( zipdrive )
|
||||||
MCFG_ATA_INTERFACE_ADD(ZIPDRIVE_ATA_TAG, ata_devices, "hdd", "hdd", false)
|
MCFG_ATA_INTERFACE_ADD(ZIPDRIVE_ATA_TAG, ata_devices, "hdd", NULL, false)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
ROM_START( zipdrive )
|
ROM_START( zipdrive )
|
||||||
|
@ -49,7 +49,7 @@ static MACHINE_CONFIG_FRAGMENT( c64_ide64 )
|
|||||||
MCFG_ATMEL_29C010_ADD(AT29C010A_TAG)
|
MCFG_ATMEL_29C010_ADD(AT29C010A_TAG)
|
||||||
MCFG_DS1302_ADD(DS1302_TAG, XTAL_32_768kHz)
|
MCFG_DS1302_ADD(DS1302_TAG, XTAL_32_768kHz)
|
||||||
|
|
||||||
MCFG_ATA_INTERFACE_ADD(ATA_TAG, ata_devices, "hdd", "hdd", false)
|
MCFG_ATA_INTERFACE_ADD(ATA_TAG, ata_devices, "hdd", NULL, false)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ WRITE_LINE_MEMBER(isa16_ide_device::ide_interrupt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MACHINE_CONFIG_FRAGMENT( ide )
|
static MACHINE_CONFIG_FRAGMENT( ide )
|
||||||
MCFG_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", "hdd", false)
|
MCFG_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", NULL, false)
|
||||||
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(isa16_ide_device, ide_interrupt))
|
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(isa16_ide_device, ide_interrupt))
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ WRITE_LINE_MEMBER(isa8_ide_device::ide_interrupt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MACHINE_CONFIG_FRAGMENT( ide8_config )
|
static MACHINE_CONFIG_FRAGMENT( ide8_config )
|
||||||
MCFG_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", "hdd", false)
|
MCFG_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", NULL, false)
|
||||||
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(isa8_ide_device, ide_interrupt))
|
MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(isa8_ide_device, ide_interrupt))
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ static MACHINE_CONFIG_FRAGMENT(kc_d004_gide)
|
|||||||
MCFG_CPU_MODIFY(Z80_TAG)
|
MCFG_CPU_MODIFY(Z80_TAG)
|
||||||
MCFG_CPU_IO_MAP(kc_d004_gide_io)
|
MCFG_CPU_IO_MAP(kc_d004_gide_io)
|
||||||
|
|
||||||
MCFG_ATA_INTERFACE_ADD(ATA_TAG, ata_devices, "hdd", "hdd", false)
|
MCFG_ATA_INTERFACE_ADD(ATA_TAG, ata_devices, "hdd", NULL, false)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user