mirror of
https://github.com/holub/mame
synced 2025-06-08 22:03:55 +03:00
turned WD33C93 into a device & made cps3 flash roms optional on cd sets (nw)
This commit is contained in:
parent
37a8c8f56f
commit
e93c3cedae
@ -13,44 +13,10 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "wd33c93.h"
|
#include "wd33c93.h"
|
||||||
#include "machine/scsidev.h"
|
|
||||||
|
|
||||||
#define VERBOSE 0
|
#define VERBOSE 0
|
||||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||||
|
|
||||||
static scsidev_device *devices[8]; // SCSI IDs 0-7
|
|
||||||
static const struct WD33C93interface *intf;
|
|
||||||
|
|
||||||
/* wd register names */
|
|
||||||
#define WD_OWN_ID 0x00
|
|
||||||
#define WD_CONTROL 0x01
|
|
||||||
#define WD_TIMEOUT_PERIOD 0x02
|
|
||||||
#define WD_CDB_1 0x03
|
|
||||||
#define WD_CDB_2 0x04
|
|
||||||
#define WD_CDB_3 0x05
|
|
||||||
#define WD_CDB_4 0x06
|
|
||||||
#define WD_CDB_5 0x07
|
|
||||||
#define WD_CDB_6 0x08
|
|
||||||
#define WD_CDB_7 0x09
|
|
||||||
#define WD_CDB_8 0x0a
|
|
||||||
#define WD_CDB_9 0x0b
|
|
||||||
#define WD_CDB_10 0x0c
|
|
||||||
#define WD_CDB_11 0x0d
|
|
||||||
#define WD_CDB_12 0x0e
|
|
||||||
#define WD_TARGET_LUN 0x0f
|
|
||||||
#define WD_COMMAND_PHASE 0x10
|
|
||||||
#define WD_SYNCHRONOUS_TRANSFER 0x11
|
|
||||||
#define WD_TRANSFER_COUNT_MSB 0x12
|
|
||||||
#define WD_TRANSFER_COUNT 0x13
|
|
||||||
#define WD_TRANSFER_COUNT_LSB 0x14
|
|
||||||
#define WD_DESTINATION_ID 0x15
|
|
||||||
#define WD_SOURCE_ID 0x16
|
|
||||||
#define WD_SCSI_STATUS 0x17
|
|
||||||
#define WD_COMMAND 0x18
|
|
||||||
#define WD_DATA 0x19
|
|
||||||
#define WD_QUEUE_TAG 0x1a
|
|
||||||
#define WD_AUXILIARY_STATUS 0x1f
|
|
||||||
|
|
||||||
/* WD commands */
|
/* WD commands */
|
||||||
#define WD_CMD_RESET 0x00
|
#define WD_CMD_RESET 0x00
|
||||||
#define WD_CMD_ABORT 0x01
|
#define WD_CMD_ABORT 0x01
|
||||||
@ -168,63 +134,37 @@ static const struct WD33C93interface *intf;
|
|||||||
#define SRCID_ES 0x40
|
#define SRCID_ES 0x40
|
||||||
#define SRCID_ER 0x80
|
#define SRCID_ER 0x80
|
||||||
|
|
||||||
/* command handler definition */
|
|
||||||
typedef void (*cmd_handler)(running_machine &machine);
|
|
||||||
#define CMD_HANDLER(name) void name(running_machine &machine)
|
|
||||||
|
|
||||||
#define TEMP_INPUT_LEN 262144
|
|
||||||
#define FIFO_SIZE 12
|
|
||||||
|
|
||||||
/* internal controller data definition */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT8 sasr;
|
|
||||||
UINT8 regs[WD_AUXILIARY_STATUS+1];
|
|
||||||
UINT8 fifo[FIFO_SIZE];
|
|
||||||
int fifo_pos;
|
|
||||||
UINT8 *temp_input;
|
|
||||||
int temp_input_pos;
|
|
||||||
UINT8 busphase;
|
|
||||||
UINT8 identify;
|
|
||||||
int read_pending;
|
|
||||||
emu_timer *cmd_timer;
|
|
||||||
} _wd33c93_data;
|
|
||||||
|
|
||||||
/* local instance of controller data */
|
|
||||||
static _wd33c93_data scsi_data;
|
|
||||||
|
|
||||||
|
|
||||||
/* convernience functions */
|
/* convernience functions */
|
||||||
static UINT8 wd33c93_getunit( void )
|
UINT8 wd33c93_device::getunit( void )
|
||||||
{
|
{
|
||||||
/* return the destination unit id */
|
/* return the destination unit id */
|
||||||
return scsi_data.regs[WD_DESTINATION_ID] & SRCID_MASK;
|
return regs[WD_DESTINATION_ID] & SRCID_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wd33c93_set_xfer_count( int count )
|
void wd33c93_device::set_xfer_count( int count )
|
||||||
{
|
{
|
||||||
/* set the count */
|
/* set the count */
|
||||||
scsi_data.regs[ WD_TRANSFER_COUNT_LSB ] = count & 0xff;
|
regs[ WD_TRANSFER_COUNT_LSB ] = count & 0xff;
|
||||||
scsi_data.regs[ WD_TRANSFER_COUNT ] = ( count >> 8 ) & 0xff;
|
regs[ WD_TRANSFER_COUNT ] = ( count >> 8 ) & 0xff;
|
||||||
scsi_data.regs[ WD_TRANSFER_COUNT_MSB ] = ( count >> 16 ) & 0xff;
|
regs[ WD_TRANSFER_COUNT_MSB ] = ( count >> 16 ) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wd33c93_get_xfer_count( void )
|
int wd33c93_device::get_xfer_count( void )
|
||||||
{
|
{
|
||||||
/* get the count */
|
/* get the count */
|
||||||
int count = scsi_data.regs[ WD_TRANSFER_COUNT_MSB ];
|
int count = regs[ WD_TRANSFER_COUNT_MSB ];
|
||||||
|
|
||||||
count <<= 8;
|
count <<= 8;
|
||||||
count |= scsi_data.regs[ WD_TRANSFER_COUNT ];
|
count |= regs[ WD_TRANSFER_COUNT ];
|
||||||
count <<= 8;
|
count <<= 8;
|
||||||
count |= scsi_data.regs[ WD_TRANSFER_COUNT_LSB ];
|
count |= regs[ WD_TRANSFER_COUNT_LSB ];
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wd33c93_read_data(int bytes, UINT8 *pData)
|
void wd33c93_device::read_data(int bytes, UINT8 *pData)
|
||||||
{
|
{
|
||||||
UINT8 unit = wd33c93_getunit();
|
UINT8 unit = getunit();
|
||||||
|
|
||||||
if ( devices[unit] )
|
if ( devices[unit] )
|
||||||
{
|
{
|
||||||
@ -236,103 +176,113 @@ static void wd33c93_read_data(int bytes, UINT8 *pData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wd33c93_complete_immediate( running_machine &machine, int status )
|
void wd33c93_device::complete_immediate( int status )
|
||||||
{
|
{
|
||||||
/* reset our timer */
|
/* reset our timer */
|
||||||
scsi_data.cmd_timer->reset( );
|
cmd_timer->reset();
|
||||||
|
|
||||||
/* set the new status */
|
/* set the new status */
|
||||||
scsi_data.regs[WD_SCSI_STATUS] = status & 0xff;
|
regs[WD_SCSI_STATUS] = status & 0xff;
|
||||||
|
|
||||||
/* set interrupt pending */
|
/* set interrupt pending */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_INT;
|
regs[WD_AUXILIARY_STATUS] |= ASR_INT;
|
||||||
|
|
||||||
/* check for error conditions */
|
/* check for error conditions */
|
||||||
if ( wd33c93_get_xfer_count() > 0 )
|
if ( get_xfer_count() > 0 )
|
||||||
{
|
{
|
||||||
/* set data buffer ready */
|
/* set data buffer ready */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_DBR;
|
regs[WD_AUXILIARY_STATUS] |= ASR_DBR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* clear data buffer ready */
|
/* clear data buffer ready */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear command in progress and bus busy */
|
/* clear command in progress and bus busy */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
|
regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
|
||||||
|
|
||||||
/* if we have a callback, call it */
|
/* if we have a callback, call it */
|
||||||
if (intf && intf->irq_callback)
|
if (irq_callback)
|
||||||
{
|
{
|
||||||
intf->irq_callback(machine, 1);
|
irq_callback(machine(), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TIMER_CALLBACK(wd33c93_complete_cb)
|
void wd33c93_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
|
||||||
{
|
{
|
||||||
wd33c93_complete_immediate( machine, param );
|
switch( tid )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
complete_immediate( param );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
complete_immediate(CSR_SRV_REQ | busphase);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_CIP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static TIMER_CALLBACK(wd33c93_service_request)
|
void wd33c93_device::complete_cmd( UINT8 status )
|
||||||
{
|
|
||||||
/* issue a message out request */
|
|
||||||
wd33c93_complete_immediate(machine, CSR_SRV_REQ | scsi_data.busphase);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TIMER_CALLBACK(wd33c93_deassert_cip)
|
|
||||||
{
|
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_CIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wd33c93_complete_cmd( UINT8 status )
|
|
||||||
{
|
{
|
||||||
/* fire off a timer to complete the command */
|
/* fire off a timer to complete the command */
|
||||||
scsi_data.cmd_timer->adjust( attotime::from_usec(1), status );
|
cmd_timer->adjust( attotime::from_usec(1), status );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* command handlers */
|
/* command handlers */
|
||||||
static CMD_HANDLER( wd33c93_invalid_cmd )
|
void wd33c93_device::unimplemented_cmd()
|
||||||
{
|
{
|
||||||
logerror( "%s:Unknown/Unimplemented SCSI controller command: %02x\n", machine.describe_context(), scsi_data.regs[WD_COMMAND] );
|
logerror( "%s:Unimplemented SCSI controller command: %02x\n", machine().describe_context(), regs[WD_COMMAND] );
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd( CSR_INVALID );
|
complete_cmd( CSR_INVALID );
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_reset_cmd )
|
void wd33c93_device::invalid_cmd()
|
||||||
{
|
{
|
||||||
int advanced = 0;
|
logerror( "%s:Invalid SCSI controller command: %02x\n", machine().describe_context(), regs[WD_COMMAND] );
|
||||||
|
|
||||||
|
/* complete the command */
|
||||||
|
complete_cmd( CSR_INVALID );
|
||||||
|
}
|
||||||
|
|
||||||
|
void wd33c93_device::reset_cmd()
|
||||||
|
{
|
||||||
|
int advanced = 0;
|
||||||
|
|
||||||
/* see if it wants us to reset with advanced features */
|
/* see if it wants us to reset with advanced features */
|
||||||
if ( scsi_data.regs[WD_OWN_ID] & OWNID_EAF )
|
if ( regs[WD_OWN_ID] & OWNID_EAF )
|
||||||
{
|
{
|
||||||
advanced = 1;
|
advanced = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear out all registers */
|
/* clear out all registers */
|
||||||
memset( scsi_data.regs, 0, sizeof( scsi_data.regs ) );
|
memset( regs, 0, sizeof( regs ) );
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd(advanced ? CSR_RESET_AF : CSR_RESET);
|
complete_cmd(advanced ? CSR_RESET_AF : CSR_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_abort_cmd )
|
void wd33c93_device::abort_cmd()
|
||||||
{
|
{
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd(CSR_ABORT);
|
complete_cmd(CSR_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_disconnect_cmd )
|
void wd33c93_device::disconnect_cmd()
|
||||||
{
|
{
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
|
regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_select_cmd )
|
void wd33c93_device::select_cmd()
|
||||||
{
|
{
|
||||||
UINT8 unit = wd33c93_getunit();
|
UINT8 unit = getunit();
|
||||||
UINT8 newstatus;
|
UINT8 newstatus;
|
||||||
|
|
||||||
/* see if we can select that device */
|
/* see if we can select that device */
|
||||||
if ( devices[unit] )
|
if ( devices[unit] )
|
||||||
@ -341,19 +291,19 @@ static CMD_HANDLER( wd33c93_select_cmd )
|
|||||||
newstatus = CSR_SELECT;
|
newstatus = CSR_SELECT;
|
||||||
|
|
||||||
/* determine the next bus phase depending on the command */
|
/* determine the next bus phase depending on the command */
|
||||||
if ( (scsi_data.regs[WD_COMMAND] & 0x7f) == WD_CMD_SEL_ATN )
|
if ( (regs[WD_COMMAND] & 0x7f) == WD_CMD_SEL_ATN )
|
||||||
{
|
{
|
||||||
/* /ATN asserted during select: Move to Message Out Phase to read identify */
|
/* /ATN asserted during select: Move to Message Out Phase to read identify */
|
||||||
scsi_data.busphase = PHS_MESS_OUT;
|
busphase = PHS_MESS_OUT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No /ATN asserted: Move to Command Phase */
|
/* No /ATN asserted: Move to Command Phase */
|
||||||
scsi_data.busphase = PHS_COMMAND;
|
busphase = PHS_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue up a service request out in the future */
|
/* queue up a service request out in the future */
|
||||||
machine.scheduler().timer_set( attotime::from_usec(50), FUNC(wd33c93_service_request ));
|
service_req_timer->adjust( attotime::from_usec(50) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -362,70 +312,70 @@ static CMD_HANDLER( wd33c93_select_cmd )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd(newstatus);
|
complete_cmd(newstatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_selectxfer_cmd )
|
void wd33c93_device::selectxfer_cmd()
|
||||||
{
|
{
|
||||||
UINT8 unit = wd33c93_getunit();
|
UINT8 unit = getunit();
|
||||||
UINT8 newstatus;
|
UINT8 newstatus;
|
||||||
|
|
||||||
/* see if we can select that device */
|
/* see if we can select that device */
|
||||||
if ( devices[unit] )
|
if ( devices[unit] )
|
||||||
{
|
{
|
||||||
if ( scsi_data.regs[WD_COMMAND_PHASE] < 0x45 )
|
if ( regs[WD_COMMAND_PHASE] < 0x45 )
|
||||||
{
|
{
|
||||||
/* device is available */
|
/* device is available */
|
||||||
int xfercount;
|
int xfercount;
|
||||||
int phase;
|
int phase;
|
||||||
|
|
||||||
/* do the request */
|
/* do the request */
|
||||||
devices[unit]->SetCommand( &scsi_data.regs[WD_CDB_1], 12 );
|
devices[unit]->SetCommand( ®s[WD_CDB_1], 12 );
|
||||||
devices[unit]->ExecCommand( &xfercount );
|
devices[unit]->ExecCommand( &xfercount );
|
||||||
devices[unit]->GetPhase( &phase );
|
devices[unit]->GetPhase( &phase );
|
||||||
|
|
||||||
/* set transfer count */
|
/* set transfer count */
|
||||||
if ( wd33c93_get_xfer_count() > TEMP_INPUT_LEN )
|
if ( get_xfer_count() > TEMP_INPUT_LEN )
|
||||||
{
|
{
|
||||||
logerror( "WD33C93: Transfer count too big. Please increase TEMP_INPUT_LEN (size=%d)\n", wd33c93_get_xfer_count() );
|
logerror( "WD33C93: Transfer count too big. Please increase TEMP_INPUT_LEN (size=%d)\n", get_xfer_count() );
|
||||||
wd33c93_set_xfer_count( TEMP_INPUT_LEN );
|
set_xfer_count( TEMP_INPUT_LEN );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( phase )
|
switch( phase )
|
||||||
{
|
{
|
||||||
case SCSI_PHASE_DATAIN:
|
case SCSI_PHASE_DATAIN:
|
||||||
scsi_data.read_pending = 1;
|
read_pending = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( scsi_data.read_pending )
|
if ( read_pending )
|
||||||
{
|
{
|
||||||
int len = TEMP_INPUT_LEN;
|
int len = TEMP_INPUT_LEN;
|
||||||
|
|
||||||
if ( wd33c93_get_xfer_count() < len ) len = wd33c93_get_xfer_count();
|
if ( get_xfer_count() < len ) len = get_xfer_count();
|
||||||
|
|
||||||
memset( &scsi_data.temp_input[0], 0, TEMP_INPUT_LEN );
|
memset( &temp_input[0], 0, TEMP_INPUT_LEN );
|
||||||
wd33c93_read_data( len, &scsi_data.temp_input[0] );
|
read_data( len, &temp_input[0] );
|
||||||
scsi_data.temp_input_pos = 0;
|
temp_input_pos = 0;
|
||||||
scsi_data.read_pending = 0;
|
read_pending = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_data.regs[WD_TARGET_LUN] = 0;
|
regs[WD_TARGET_LUN] = 0;
|
||||||
scsi_data.regs[WD_CONTROL] |= CTRL_EDI;
|
regs[WD_CONTROL] |= CTRL_EDI;
|
||||||
scsi_data.regs[WD_COMMAND_PHASE] = 0x60;
|
regs[WD_COMMAND_PHASE] = 0x60;
|
||||||
|
|
||||||
/* signal transfer ready */
|
/* signal transfer ready */
|
||||||
newstatus = CSR_SEL_XFER_DONE;
|
newstatus = CSR_SEL_XFER_DONE;
|
||||||
|
|
||||||
/* if allowed disconnect, queue a service request */
|
/* if allowed disconnect, queue a service request */
|
||||||
if ( scsi_data.identify & 0x40 )
|
if ( identify & 0x40 )
|
||||||
{
|
{
|
||||||
/* queue disconnect message in */
|
/* queue disconnect message in */
|
||||||
scsi_data.busphase = PHS_MESS_IN;
|
busphase = PHS_MESS_IN;
|
||||||
|
|
||||||
/* queue up a service request out in the future */
|
/* queue up a service request out in the future */
|
||||||
machine.scheduler().timer_set( attotime::from_msec(50), FUNC(wd33c93_service_request ));
|
service_req_timer->adjust( attotime::from_usec(50) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -433,189 +383,199 @@ static CMD_HANDLER( wd33c93_selectxfer_cmd )
|
|||||||
/* device is not available */
|
/* device is not available */
|
||||||
newstatus = CSR_TIMEOUT;
|
newstatus = CSR_TIMEOUT;
|
||||||
|
|
||||||
wd33c93_set_xfer_count( 0 );
|
set_xfer_count( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd(newstatus);
|
complete_cmd(newstatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_negate_ack )
|
void wd33c93_device::negate_ack()
|
||||||
{
|
{
|
||||||
logerror( "WD33C93: ACK Negated\n" );
|
logerror( "WD33C93: ACK Negated\n" );
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
|
regs[WD_AUXILIARY_STATUS] &= ~(ASR_CIP | ASR_BSY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CMD_HANDLER( wd33c93_xferinfo_cmd )
|
void wd33c93_device::xferinfo_cmd()
|
||||||
{
|
{
|
||||||
/* make the buffer available right away */
|
/* make the buffer available right away */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_DBR;
|
regs[WD_AUXILIARY_STATUS] |= ASR_DBR;
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_CIP;
|
regs[WD_AUXILIARY_STATUS] |= ASR_CIP;
|
||||||
|
|
||||||
/* the command will be completed once the data is transferred */
|
/* the command will be completed once the data is transferred */
|
||||||
machine.scheduler().timer_set( attotime::from_msec(1), FUNC(wd33c93_deassert_cip ));
|
deassert_cip_timer->adjust( attotime::from_msec(1) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Command handlers */
|
|
||||||
static const cmd_handler wd33c93_cmds[0x22] =
|
|
||||||
{
|
|
||||||
&wd33c93_reset_cmd, /* 0x00 - WD_CMD_RESET */
|
|
||||||
&wd33c93_abort_cmd, /* 0x01 - WD_CMD_ABORT */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x02 - WD_CMD_ASSERT_ATN (uninmplemented) */
|
|
||||||
&wd33c93_negate_ack, /* 0x03 - WD_CMD_NEGATE_ACK */
|
|
||||||
&wd33c93_disconnect_cmd,/* 0x04 - WD_CMD_DISCONNECT */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x05 - WD_CMD_RESELECT (uninmplemented) */
|
|
||||||
&wd33c93_select_cmd, /* 0x06 - WD_CMD_SEL_ATN */
|
|
||||||
&wd33c93_select_cmd, /* 0x07 - WD_CMD_SEL */
|
|
||||||
&wd33c93_selectxfer_cmd,/* 0x08 - WD_CMD_SEL_ATN_XFER */
|
|
||||||
&wd33c93_selectxfer_cmd,/* 0x09 - WD_CMD_SEL_XFER */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x0a - WD_CMD_RESEL_RECEIVE (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x0b - WD_CMD_RESEL_SEND (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x0c - WD_CMD_WAIT_SEL_RECEIVE (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x0d - WD_CMD_SSCC (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x0e - WD_CMD_SND_DISC (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x0f - WD_CMD_SET_IDI (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x10 - WD_CMD_RCV_CMD (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x11 - WD_CMD_RCV_DATA (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x12 - WD_CMD_RCV_MSG_OUT (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x13 - WD_CMD_RCV (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x14 - WD_CMD_SND_STATUS (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x15 - WD_CMD_SND_DATA (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x16 - WD_CMD_SND_MSG_IN (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x17 - WD_CMD_SND (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x18 - WD_CMD_TRANS_ADDR (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x19 - WD_CMD_XFER_PAD (uninmplemented) */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x1a - invalid */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x1b - invalid */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x1c - invalid */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x1d - invalid */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x1e - invalid */
|
|
||||||
&wd33c93_invalid_cmd, /* 0x1f - invalid */
|
|
||||||
&wd33c93_xferinfo_cmd, /* 0x20 - WD_CMD_TRANS_INFO) */
|
|
||||||
&wd33c93_invalid_cmd /* 0x21 - WD_CMD_TRANSFER_PAD (uninmplemented) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Handle pending commands */
|
/* Handle pending commands */
|
||||||
static void wd33c93_command( running_machine &machine )
|
void wd33c93_device::dispatch_command()
|
||||||
{
|
{
|
||||||
/* get the command */
|
/* get the command */
|
||||||
UINT8 cmd = scsi_data.regs[WD_COMMAND];
|
UINT8 cmd = regs[WD_COMMAND] & 0x7f;
|
||||||
|
|
||||||
/* check if its within valid bounds */
|
switch(cmd)
|
||||||
if ( (cmd & 0x7F) > WD_CMD_TRANSFER_PAD )
|
|
||||||
{
|
{
|
||||||
wd33c93_invalid_cmd(machine);
|
case WD_CMD_RESET:
|
||||||
return;
|
reset_cmd();
|
||||||
}
|
break;
|
||||||
|
|
||||||
/* call the command handler */
|
case WD_CMD_ABORT:
|
||||||
(*wd33c93_cmds[cmd & 0x7F])(machine);
|
abort_cmd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WD_CMD_NEGATE_ACK:
|
||||||
|
negate_ack();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WD_CMD_DISCONNECT:
|
||||||
|
disconnect_cmd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WD_CMD_SEL_ATN:
|
||||||
|
case WD_CMD_SEL:
|
||||||
|
select_cmd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WD_CMD_SEL_ATN_XFER:
|
||||||
|
case WD_CMD_SEL_XFER:
|
||||||
|
selectxfer_cmd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WD_CMD_TRANS_INFO:
|
||||||
|
xferinfo_cmd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WD_CMD_ASSERT_ATN:
|
||||||
|
case WD_CMD_RESELECT:
|
||||||
|
case WD_CMD_RESEL_RECEIVE:
|
||||||
|
case WD_CMD_RESEL_SEND:
|
||||||
|
case WD_CMD_WAIT_SEL_RECEIVE:
|
||||||
|
case WD_CMD_SSCC:
|
||||||
|
case WD_CMD_SND_DISC:
|
||||||
|
case WD_CMD_SET_IDI:
|
||||||
|
case WD_CMD_RCV_CMD:
|
||||||
|
case WD_CMD_RCV_DATA:
|
||||||
|
case WD_CMD_RCV_MSG_OUT:
|
||||||
|
case WD_CMD_RCV:
|
||||||
|
case WD_CMD_SND_STATUS:
|
||||||
|
case WD_CMD_SND_DATA:
|
||||||
|
case WD_CMD_SND_MSG_IN:
|
||||||
|
case WD_CMD_SND:
|
||||||
|
case WD_CMD_TRANS_ADDR:
|
||||||
|
case WD_CMD_XFER_PAD:
|
||||||
|
case WD_CMD_TRANSFER_PAD:
|
||||||
|
unimplemented_cmd();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
invalid_cmd();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WRITE8_HANDLER(wd33c93_w)
|
WRITE8_MEMBER(wd33c93_device::write)
|
||||||
{
|
{
|
||||||
switch( offset )
|
switch( offset )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
/* update register select */
|
/* update register select */
|
||||||
scsi_data.sasr = data & 0x1f;
|
sasr = data & 0x1f;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
LOG(( "WD33C93: PC=%08x - Write REG=%02x, data = %02x\n", cpu_get_pc(&space->device()), scsi_data.sasr, data ));
|
LOG(( "WD33C93: PC=%08x - Write REG=%02x, data = %02x\n", cpu_get_pc(&space.device()), sasr, data ));
|
||||||
|
|
||||||
/* update the register */
|
/* update the register */
|
||||||
scsi_data.regs[scsi_data.sasr] = data;
|
regs[sasr] = data;
|
||||||
|
|
||||||
/* if we receive a command, schedule to process it */
|
/* if we receive a command, schedule to process it */
|
||||||
if ( scsi_data.sasr == WD_COMMAND )
|
if ( sasr == WD_COMMAND )
|
||||||
{
|
{
|
||||||
LOG(( "WDC33C93: PC=%08x - Executing command %08x - unit %d\n", cpu_get_pc(&space->device()), data, wd33c93_getunit() ));
|
LOG(( "WDC33C93: PC=%08x - Executing command %08x - unit %d\n", cpu_get_pc(&space.device()), data, getunit() ));
|
||||||
|
|
||||||
/* signal we're processing it */
|
/* signal we're processing it */
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_CIP;
|
regs[WD_AUXILIARY_STATUS] |= ASR_CIP;
|
||||||
|
|
||||||
/* process the command */
|
/* process the command */
|
||||||
wd33c93_command(space->machine());
|
dispatch_command();
|
||||||
}
|
}
|
||||||
else if ( scsi_data.sasr == WD_CDB_1 )
|
else if ( sasr == WD_CDB_1 )
|
||||||
{
|
{
|
||||||
scsi_data.regs[WD_COMMAND_PHASE] = 0;
|
regs[WD_COMMAND_PHASE] = 0;
|
||||||
}
|
}
|
||||||
else if ( scsi_data.sasr == WD_DATA )
|
else if ( sasr == WD_DATA )
|
||||||
{
|
{
|
||||||
/* if data was written, and we have a count, send to device */
|
/* if data was written, and we have a count, send to device */
|
||||||
int count = wd33c93_get_xfer_count();
|
int count = get_xfer_count();
|
||||||
|
|
||||||
if ( scsi_data.regs[WD_COMMAND] & 0x80 )
|
if ( regs[WD_COMMAND] & 0x80 )
|
||||||
count = 1;
|
count = 1;
|
||||||
|
|
||||||
if ( count-- > 0 )
|
if ( count-- > 0 )
|
||||||
{
|
{
|
||||||
/* write to FIFO */
|
/* write to FIFO */
|
||||||
if ( scsi_data.fifo_pos < FIFO_SIZE )
|
if ( fifo_pos < FIFO_SIZE )
|
||||||
{
|
{
|
||||||
scsi_data.fifo[scsi_data.fifo_pos++] = data;
|
fifo[fifo_pos++] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update count */
|
/* update count */
|
||||||
wd33c93_set_xfer_count( count );
|
set_xfer_count( count );
|
||||||
|
|
||||||
/* if we're done with the write, see where we're at */
|
/* if we're done with the write, see where we're at */
|
||||||
if ( count == 0 )
|
if ( count == 0 )
|
||||||
{
|
{
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_INT;
|
regs[WD_AUXILIARY_STATUS] |= ASR_INT;
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
||||||
|
|
||||||
switch( scsi_data.busphase )
|
switch( busphase )
|
||||||
{
|
{
|
||||||
case PHS_MESS_OUT:
|
case PHS_MESS_OUT:
|
||||||
{
|
{
|
||||||
/* reset fifo */
|
/* reset fifo */
|
||||||
scsi_data.fifo_pos = 0;
|
fifo_pos = 0;
|
||||||
|
|
||||||
/* Message out phase. Data is probably SCSI Identify. Move to command phase. */
|
/* Message out phase. Data is probably SCSI Identify. Move to command phase. */
|
||||||
scsi_data.busphase = PHS_COMMAND;
|
busphase = PHS_COMMAND;
|
||||||
|
|
||||||
scsi_data.identify = scsi_data.fifo[0];
|
identify = fifo[0];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PHS_COMMAND:
|
case PHS_COMMAND:
|
||||||
{
|
{
|
||||||
UINT8 unit = wd33c93_getunit();
|
UINT8 unit = getunit();
|
||||||
int xfercount;
|
int xfercount;
|
||||||
int phase;
|
int phase;
|
||||||
|
|
||||||
/* Execute the command. Depending on the command, we'll move to data in or out */
|
/* Execute the command. Depending on the command, we'll move to data in or out */
|
||||||
devices[unit]->SetCommand( &scsi_data.fifo[0], 12 );
|
devices[unit]->SetCommand( &fifo[0], 12 );
|
||||||
devices[unit]->ExecCommand( &xfercount );
|
devices[unit]->ExecCommand( &xfercount );
|
||||||
devices[unit]->GetPhase( &phase );
|
devices[unit]->GetPhase( &phase );
|
||||||
|
|
||||||
/* reset fifo */
|
/* reset fifo */
|
||||||
scsi_data.fifo_pos = 0;
|
fifo_pos = 0;
|
||||||
|
|
||||||
/* set the new count */
|
/* set the new count */
|
||||||
wd33c93_set_xfer_count( xfercount );
|
set_xfer_count( xfercount );
|
||||||
|
|
||||||
switch( phase )
|
switch( phase )
|
||||||
{
|
{
|
||||||
case SCSI_PHASE_STATUS:
|
case SCSI_PHASE_STATUS:
|
||||||
scsi_data.busphase = PHS_STATUS;
|
busphase = PHS_STATUS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_PHASE_DATAIN:
|
case SCSI_PHASE_DATAIN:
|
||||||
scsi_data.busphase = PHS_DATA_IN;
|
busphase = PHS_DATA_IN;
|
||||||
scsi_data.read_pending = 1;
|
read_pending = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCSI_PHASE_DATAOUT:
|
case SCSI_PHASE_DATAOUT:
|
||||||
scsi_data.busphase = PHS_DATA_OUT;
|
busphase = PHS_DATA_OUT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -624,19 +584,19 @@ WRITE8_HANDLER(wd33c93_w)
|
|||||||
case PHS_DATA_OUT:
|
case PHS_DATA_OUT:
|
||||||
{
|
{
|
||||||
/* write data out to device */
|
/* write data out to device */
|
||||||
wd33c93_write_data( scsi_data.fifo_pos, scsi_data.fifo );
|
write_data( fifo_pos, fifo );
|
||||||
|
|
||||||
/* reset fifo */
|
/* reset fifo */
|
||||||
scsi_data.fifo_pos = 0;
|
fifo_pos = 0;
|
||||||
|
|
||||||
/* move to status phase */
|
/* move to status phase */
|
||||||
scsi_data.busphase = PHS_STATUS;
|
busphase = PHS_STATUS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_immediate(space->machine(), CSR_XFER_DONE | scsi_data.busphase);
|
complete_immediate(CSR_XFER_DONE | busphase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -646,9 +606,9 @@ WRITE8_HANDLER(wd33c93_w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* auto-increment register select if not on special registers */
|
/* auto-increment register select if not on special registers */
|
||||||
if ( scsi_data.sasr != WD_COMMAND && scsi_data.sasr != WD_DATA && scsi_data.sasr != WD_AUXILIARY_STATUS )
|
if ( sasr != WD_COMMAND && sasr != WD_DATA && sasr != WD_AUXILIARY_STATUS )
|
||||||
{
|
{
|
||||||
scsi_data.sasr = ( scsi_data.sasr + 1 ) & 0x1f;
|
sasr = ( sasr + 1 ) & 0x1f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -661,109 +621,109 @@ WRITE8_HANDLER(wd33c93_w)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
READ8_HANDLER(wd33c93_r)
|
READ8_MEMBER(wd33c93_device::read)
|
||||||
{
|
{
|
||||||
switch( offset )
|
switch( offset )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
/* read aux status */
|
/* read aux status */
|
||||||
return scsi_data.regs[WD_AUXILIARY_STATUS];
|
return regs[WD_AUXILIARY_STATUS];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
UINT8 ret;
|
UINT8 ret;
|
||||||
|
|
||||||
/* if reading status, clear irq flag */
|
/* if reading status, clear irq flag */
|
||||||
if ( scsi_data.sasr == WD_SCSI_STATUS )
|
if ( sasr == WD_SCSI_STATUS )
|
||||||
{
|
{
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_INT;
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_INT;
|
||||||
|
|
||||||
if (intf && intf->irq_callback)
|
if (irq_callback)
|
||||||
{
|
{
|
||||||
intf->irq_callback(space->machine(), 0);
|
irq_callback(machine(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(( "WD33C93: PC=%08x - Status read (%02x)\n", cpu_get_pc(&space->device()), scsi_data.regs[WD_SCSI_STATUS] ));
|
LOG(( "WD33C93: PC=%08x - Status read (%02x)\n", cpu_get_pc(&space.device()), regs[WD_SCSI_STATUS] ));
|
||||||
}
|
}
|
||||||
else if ( scsi_data.sasr == WD_DATA )
|
else if ( sasr == WD_DATA )
|
||||||
{
|
{
|
||||||
/* we're going to be doing synchronous reads */
|
/* we're going to be doing synchronous reads */
|
||||||
|
|
||||||
/* get the transfer count */
|
/* get the transfer count */
|
||||||
int count = wd33c93_get_xfer_count();
|
int count = get_xfer_count();
|
||||||
|
|
||||||
/* initialize the return value */
|
/* initialize the return value */
|
||||||
scsi_data.regs[WD_DATA] = 0;
|
regs[WD_DATA] = 0;
|
||||||
|
|
||||||
if ( count <= 0 && scsi_data.busphase == PHS_MESS_IN )
|
if ( count <= 0 && busphase == PHS_MESS_IN )
|
||||||
{
|
{
|
||||||
/* move to disconnect */
|
/* move to disconnect */
|
||||||
wd33c93_complete_cmd(CSR_DISC);
|
complete_cmd(CSR_DISC);
|
||||||
}
|
}
|
||||||
else if ( count == 1 && scsi_data.busphase == PHS_STATUS )
|
else if ( count == 1 && busphase == PHS_STATUS )
|
||||||
{
|
{
|
||||||
/* update the count */
|
/* update the count */
|
||||||
wd33c93_set_xfer_count( 0 );
|
set_xfer_count( 0 );
|
||||||
|
|
||||||
/* move to message in phase */
|
/* move to message in phase */
|
||||||
scsi_data.busphase = PHS_MESS_IN;
|
busphase = PHS_MESS_IN;
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd(CSR_XFER_DONE | scsi_data.busphase);
|
complete_cmd(CSR_XFER_DONE | busphase);
|
||||||
}
|
}
|
||||||
else if ( count-- > 0 ) /* make sure we still have data to send */
|
else if ( count-- > 0 ) /* make sure we still have data to send */
|
||||||
{
|
{
|
||||||
if ( scsi_data.read_pending )
|
if ( read_pending )
|
||||||
{
|
{
|
||||||
int len = TEMP_INPUT_LEN;
|
int len = TEMP_INPUT_LEN;
|
||||||
|
|
||||||
if ( (count+1) < len ) len = count+1;
|
if ( (count+1) < len ) len = count+1;
|
||||||
wd33c93_read_data( len, &scsi_data.temp_input[0] );
|
read_data( len, &temp_input[0] );
|
||||||
scsi_data.temp_input_pos = 0;
|
temp_input_pos = 0;
|
||||||
scsi_data.read_pending = 0;
|
read_pending = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_INT;
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_INT;
|
||||||
|
|
||||||
/* read in one byte */
|
/* read in one byte */
|
||||||
if ( scsi_data.temp_input_pos < TEMP_INPUT_LEN )
|
if ( temp_input_pos < TEMP_INPUT_LEN )
|
||||||
scsi_data.regs[WD_DATA] = scsi_data.temp_input[scsi_data.temp_input_pos++];
|
regs[WD_DATA] = temp_input[temp_input_pos++];
|
||||||
|
|
||||||
/* update the count */
|
/* update the count */
|
||||||
wd33c93_set_xfer_count( count );
|
set_xfer_count( count );
|
||||||
|
|
||||||
/* transfer finished, see where we're at */
|
/* transfer finished, see where we're at */
|
||||||
if ( count == 0 )
|
if ( count == 0 )
|
||||||
{
|
{
|
||||||
if ( scsi_data.regs[WD_COMMAND_PHASE] != 0x60 )
|
if ( regs[WD_COMMAND_PHASE] != 0x60 )
|
||||||
{
|
{
|
||||||
/* move to status phase */
|
/* move to status phase */
|
||||||
scsi_data.busphase = PHS_STATUS;
|
busphase = PHS_STATUS;
|
||||||
|
|
||||||
/* complete the command */
|
/* complete the command */
|
||||||
wd33c93_complete_cmd(CSR_XFER_DONE | scsi_data.busphase);
|
complete_cmd(CSR_XFER_DONE | busphase);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] |= ASR_INT;
|
regs[WD_AUXILIARY_STATUS] |= ASR_INT;
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(( "WD33C93: PC=%08x - Data read (%02x)\n", cpu_get_pc(&space->device()), scsi_data.regs[WD_DATA] ));
|
LOG(( "WD33C93: PC=%08x - Data read (%02x)\n", cpu_get_pc(&space.device()), regs[WD_DATA] ));
|
||||||
|
|
||||||
/* get the register value */
|
/* get the register value */
|
||||||
ret = scsi_data.regs[scsi_data.sasr];
|
ret = regs[sasr];
|
||||||
|
|
||||||
/* auto-increment register select if not on special registers */
|
/* auto-increment register select if not on special registers */
|
||||||
if ( scsi_data.sasr != WD_COMMAND && scsi_data.sasr != WD_DATA && scsi_data.sasr != WD_AUXILIARY_STATUS )
|
if ( sasr != WD_COMMAND && sasr != WD_DATA && sasr != WD_AUXILIARY_STATUS )
|
||||||
{
|
{
|
||||||
scsi_data.sasr = ( scsi_data.sasr + 1 ) & 0x1f;
|
sasr = ( sasr + 1 ) & 0x1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -779,40 +739,56 @@ READ8_HANDLER(wd33c93_r)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wd33c93_init( running_machine &machine, const struct WD33C93interface *interface )
|
wd33c93_device::wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||||
|
: device_t(mconfig, WD33C93, "33C93 SCSI", tag, owner, clock)
|
||||||
{
|
{
|
||||||
// save interface pointer for later
|
}
|
||||||
intf = interface;
|
|
||||||
|
|
||||||
memset(&scsi_data, 0, sizeof(scsi_data));
|
void wd33c93_device::device_start()
|
||||||
|
{
|
||||||
|
memset(®s, 0, sizeof(regs));
|
||||||
memset(devices, 0, sizeof(devices));
|
memset(devices, 0, sizeof(devices));
|
||||||
|
|
||||||
// try to open the devices
|
// try to open the devices
|
||||||
for (int i = 0; i < interface->scsidevs->devs_present; i++)
|
for (int i = 0; i < scsidevs->devs_present; i++)
|
||||||
{
|
{
|
||||||
scsidev_device *device = machine.device<scsidev_device>( interface->scsidevs->devices[i].tag );
|
scsidev_device *device = machine().device<scsidev_device>( scsidevs->devices[i].tag );
|
||||||
devices[device->GetDeviceID()] = device;
|
devices[device->GetDeviceID()] = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate a timer for commands */
|
/* allocate a timer for commands */
|
||||||
scsi_data.cmd_timer = machine.scheduler().timer_alloc(FUNC(wd33c93_complete_cb));
|
cmd_timer = timer_alloc(0);
|
||||||
|
service_req_timer = timer_alloc(1);
|
||||||
|
deassert_cip_timer = timer_alloc(2);
|
||||||
|
|
||||||
scsi_data.temp_input = auto_alloc_array( machine, UINT8, TEMP_INPUT_LEN );
|
save_item( NAME( sasr ) );
|
||||||
|
save_item( NAME( regs ) );
|
||||||
// state_save_register_item_array(machine, "wd33c93", NULL, 0, scsi_data);
|
save_item( NAME( fifo ) );
|
||||||
|
save_item( NAME( fifo_pos ) );
|
||||||
|
save_item( NAME( temp_input ) );
|
||||||
|
save_item( NAME( temp_input_pos ) );
|
||||||
|
save_item( NAME( busphase ) );
|
||||||
|
save_item( NAME( identify ) );
|
||||||
|
save_item( NAME( read_pending ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wd33c93_get_dma_data( int bytes, UINT8 *pData )
|
void wd33c93_device::static_set_interface(device_t &device, const WD33C93interface &interface)
|
||||||
{
|
{
|
||||||
int len = bytes;
|
wd33c93_device &wd33c93 = downcast<wd33c93_device &>(device);
|
||||||
|
static_cast<WD33C93interface &>(wd33c93) = interface;
|
||||||
|
}
|
||||||
|
|
||||||
if ( len >= wd33c93_get_xfer_count() )
|
void wd33c93_device::get_dma_data( int bytes, UINT8 *pData )
|
||||||
len = wd33c93_get_xfer_count();
|
{
|
||||||
|
int len = bytes;
|
||||||
|
|
||||||
|
if ( len >= get_xfer_count() )
|
||||||
|
len = get_xfer_count();
|
||||||
|
|
||||||
if ( len == 0 )
|
if ( len == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( (scsi_data.temp_input_pos+len) >= TEMP_INPUT_LEN )
|
if ( (temp_input_pos+len) >= TEMP_INPUT_LEN )
|
||||||
{
|
{
|
||||||
logerror( "Reading past end of buffer, increase TEMP_INPUT_LEN size\n" );
|
logerror( "Reading past end of buffer, increase TEMP_INPUT_LEN size\n" );
|
||||||
len = TEMP_INPUT_LEN - len;
|
len = TEMP_INPUT_LEN - len;
|
||||||
@ -820,16 +796,16 @@ void wd33c93_get_dma_data( int bytes, UINT8 *pData )
|
|||||||
|
|
||||||
assert(len);
|
assert(len);
|
||||||
|
|
||||||
memcpy( pData, &scsi_data.temp_input[scsi_data.temp_input_pos], len );
|
memcpy( pData, &temp_input[temp_input_pos], len );
|
||||||
|
|
||||||
scsi_data.temp_input_pos += len;
|
temp_input_pos += len;
|
||||||
len = wd33c93_get_xfer_count() - len;
|
len = get_xfer_count() - len;
|
||||||
wd33c93_set_xfer_count(len);
|
set_xfer_count(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wd33c93_write_data(int bytes, UINT8 *pData)
|
void wd33c93_device::write_data(int bytes, UINT8 *pData)
|
||||||
{
|
{
|
||||||
UINT8 unit = wd33c93_getunit();
|
UINT8 unit = getunit();
|
||||||
|
|
||||||
if (devices[unit])
|
if (devices[unit])
|
||||||
{
|
{
|
||||||
@ -841,14 +817,16 @@ void wd33c93_write_data(int bytes, UINT8 *pData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wd33c93_clear_dma(void)
|
void wd33c93_device::clear_dma()
|
||||||
{
|
{
|
||||||
/* indicate DMA completed by clearing the transfer count */
|
/* indicate DMA completed by clearing the transfer count */
|
||||||
wd33c93_set_xfer_count(0);
|
set_xfer_count(0);
|
||||||
scsi_data.regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
regs[WD_AUXILIARY_STATUS] &= ~ASR_DBR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wd33c93_get_dma_count(void)
|
int wd33c93_device::get_dma_count()
|
||||||
{
|
{
|
||||||
return wd33c93_get_xfer_count();
|
return get_xfer_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const device_type WD33C93 = &device_creator<wd33c93_device>;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define _WD33C93_H_
|
#define _WD33C93_H_
|
||||||
|
|
||||||
#include "machine/scsi.h"
|
#include "machine/scsi.h"
|
||||||
|
#include "scsidev.h"
|
||||||
|
|
||||||
struct WD33C93interface
|
struct WD33C93interface
|
||||||
{
|
{
|
||||||
@ -14,12 +15,105 @@ struct WD33C93interface
|
|||||||
void (*irq_callback)(running_machine &machine, int state); /* irq callback */
|
void (*irq_callback)(running_machine &machine, int state); /* irq callback */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void wd33c93_init( running_machine &machine, const struct WD33C93interface *interface );
|
/* wd register names */
|
||||||
extern void wd33c93_get_dma_data(int bytes, UINT8 *pData);
|
|
||||||
extern void wd33c93_write_data(int bytes, UINT8 *pData);
|
enum
|
||||||
extern void wd33c93_clear_dma(void);
|
{
|
||||||
extern int wd33c93_get_dma_count(void);
|
WD_OWN_ID = 0x00,
|
||||||
extern READ8_HANDLER(wd33c93_r);
|
WD_CONTROL = 0x01,
|
||||||
extern WRITE8_HANDLER(wd33c93_w);
|
WD_TIMEOUT_PERIOD = 0x02,
|
||||||
|
WD_CDB_1 = 0x03,
|
||||||
|
WD_CDB_2 = 0x04,
|
||||||
|
WD_CDB_3 = 0x05,
|
||||||
|
WD_CDB_4 = 0x06,
|
||||||
|
WD_CDB_5 = 0x07,
|
||||||
|
WD_CDB_6 = 0x08,
|
||||||
|
WD_CDB_7 = 0x09,
|
||||||
|
WD_CDB_8 = 0x0a,
|
||||||
|
WD_CDB_9 = 0x0b,
|
||||||
|
WD_CDB_10 = 0x0c,
|
||||||
|
WD_CDB_11 = 0x0d,
|
||||||
|
WD_CDB_12 = 0x0e,
|
||||||
|
WD_TARGET_LUN = 0x0f,
|
||||||
|
WD_COMMAND_PHASE = 0x10,
|
||||||
|
WD_SYNCHRONOUS_TRANSFER = 0x11,
|
||||||
|
WD_TRANSFER_COUNT_MSB = 0x12,
|
||||||
|
WD_TRANSFER_COUNT = 0x13,
|
||||||
|
WD_TRANSFER_COUNT_LSB = 0x14,
|
||||||
|
WD_DESTINATION_ID = 0x15,
|
||||||
|
WD_SOURCE_ID = 0x16,
|
||||||
|
WD_SCSI_STATUS = 0x17,
|
||||||
|
WD_COMMAND = 0x18,
|
||||||
|
WD_DATA = 0x19,
|
||||||
|
WD_QUEUE_TAG = 0x1a,
|
||||||
|
WD_AUXILIARY_STATUS = 0x1f
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TEMP_INPUT_LEN 262144
|
||||||
|
#define FIFO_SIZE 12
|
||||||
|
|
||||||
|
#define MCFG_WD33C93_ADD( _tag, _interface ) \
|
||||||
|
MCFG_DEVICE_ADD( _tag, WD33C93, 0 ) \
|
||||||
|
wd33c93_device::static_set_interface(*device, _interface);
|
||||||
|
|
||||||
|
class wd33c93_device : public device_t,
|
||||||
|
public WD33C93interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
wd33c93_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||||
|
|
||||||
|
// inline configuration helpers
|
||||||
|
static void static_set_interface(device_t &device, const WD33C93interface &interface);
|
||||||
|
|
||||||
|
DECLARE_READ8_MEMBER(read);
|
||||||
|
DECLARE_WRITE8_MEMBER(write);
|
||||||
|
|
||||||
|
void get_dma_data( int bytes, UINT8 *pData );
|
||||||
|
void write_data(int bytes, UINT8 *pData);
|
||||||
|
void clear_dma();
|
||||||
|
int get_dma_count();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start();
|
||||||
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
UINT8 getunit( void );
|
||||||
|
void set_xfer_count( int count );
|
||||||
|
int get_xfer_count( void );
|
||||||
|
void read_data(int bytes, UINT8 *pData);
|
||||||
|
void complete_immediate( int status );
|
||||||
|
void complete_cmd( UINT8 status );
|
||||||
|
void unimplemented_cmd();
|
||||||
|
void invalid_cmd();
|
||||||
|
void reset_cmd();
|
||||||
|
void abort_cmd();
|
||||||
|
void disconnect_cmd();
|
||||||
|
void select_cmd();
|
||||||
|
void selectxfer_cmd();
|
||||||
|
void negate_ack();
|
||||||
|
void xferinfo_cmd();
|
||||||
|
void dispatch_command();
|
||||||
|
|
||||||
|
scsidev_device *devices[8]; // SCSI IDs 0-7
|
||||||
|
|
||||||
|
UINT8 sasr;
|
||||||
|
UINT8 regs[WD_AUXILIARY_STATUS+1];
|
||||||
|
UINT8 fifo[FIFO_SIZE];
|
||||||
|
int fifo_pos;
|
||||||
|
UINT8 temp_input[TEMP_INPUT_LEN];
|
||||||
|
int temp_input_pos;
|
||||||
|
UINT8 busphase;
|
||||||
|
UINT8 identify;
|
||||||
|
int read_pending;
|
||||||
|
emu_timer *cmd_timer;
|
||||||
|
emu_timer *service_req_timer;
|
||||||
|
emu_timer *deassert_cip_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
extern const device_type WD33C93;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -87,8 +87,6 @@ public:
|
|||||||
DECLARE_READ32_MEMBER(cps3_40C0004_r);
|
DECLARE_READ32_MEMBER(cps3_40C0004_r);
|
||||||
DECLARE_READ32_MEMBER(cps3_eeprom_r);
|
DECLARE_READ32_MEMBER(cps3_eeprom_r);
|
||||||
DECLARE_WRITE32_MEMBER(cps3_eeprom_w);
|
DECLARE_WRITE32_MEMBER(cps3_eeprom_w);
|
||||||
DECLARE_READ32_MEMBER(cps3_cdrom_r);
|
|
||||||
DECLARE_WRITE32_MEMBER(cps3_cdrom_w);
|
|
||||||
DECLARE_WRITE32_MEMBER(cps3_ss_bank_base_w);
|
DECLARE_WRITE32_MEMBER(cps3_ss_bank_base_w);
|
||||||
DECLARE_WRITE32_MEMBER(cps3_ss_pal_base_w);
|
DECLARE_WRITE32_MEMBER(cps3_ss_pal_base_w);
|
||||||
DECLARE_WRITE32_MEMBER(cps3_palettedma_w);
|
DECLARE_WRITE32_MEMBER(cps3_palettedma_w);
|
||||||
|
@ -49,7 +49,10 @@ class ip20_state : public driver_device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ip20_state(const machine_config &mconfig, device_type type, const char *tag)
|
ip20_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: driver_device(mconfig, type, tag) { }
|
: driver_device(mconfig, type, tag),
|
||||||
|
m_wd33c93(*this, "wd33c93"){ }
|
||||||
|
|
||||||
|
required_device<wd33c93_device> m_wd33c93;
|
||||||
|
|
||||||
HPC_t m_HPC;
|
HPC_t m_HPC;
|
||||||
RTC_t m_RTC;
|
RTC_t m_RTC;
|
||||||
@ -131,7 +134,7 @@ READ32_MEMBER(ip20_state::hpc_r)
|
|||||||
case 0x0120:
|
case 0x0120:
|
||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
{
|
{
|
||||||
return ( wd33c93_r( &space, 0 ) << 8 );
|
return ( m_wd33c93->read( space, 0 ) << 8 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -140,7 +143,7 @@ READ32_MEMBER(ip20_state::hpc_r)
|
|||||||
case 0x0124:
|
case 0x0124:
|
||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
{
|
{
|
||||||
return ( wd33c93_r( &space, 1 ) << 8 );
|
return ( m_wd33c93->read( space, 1 ) << 8 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -288,7 +291,7 @@ WRITE32_MEMBER(ip20_state::hpc_w)
|
|||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
{
|
{
|
||||||
verboselog(machine(), 2, "HPC SCSI Controller Register Write: %08x\n", ( data >> 8 ) & 0x000000ff );
|
verboselog(machine(), 2, "HPC SCSI Controller Register Write: %08x\n", ( data >> 8 ) & 0x000000ff );
|
||||||
wd33c93_w( &space, 0, ( data >> 8 ) & 0x000000ff );
|
m_wd33c93->write( space, 0, ( data >> 8 ) & 0x000000ff );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -299,7 +302,7 @@ WRITE32_MEMBER(ip20_state::hpc_w)
|
|||||||
if (ACCESSING_BITS_8_15)
|
if (ACCESSING_BITS_8_15)
|
||||||
{
|
{
|
||||||
verboselog(machine(), 2, "HPC SCSI Controller Data Write: %08x\n", ( data >> 8 ) & 0x000000ff );
|
verboselog(machine(), 2, "HPC SCSI Controller Data Write: %08x\n", ( data >> 8 ) & 0x000000ff );
|
||||||
wd33c93_w( &space, 1, ( data >> 8 ) & 0x000000ff );
|
m_wd33c93->write( space, 1, ( data >> 8 ) & 0x000000ff );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -562,8 +565,6 @@ static MACHINE_START( ip204415 )
|
|||||||
{
|
{
|
||||||
ip20_state *state = machine.driver_data<ip20_state>();
|
ip20_state *state = machine.driver_data<ip20_state>();
|
||||||
|
|
||||||
wd33c93_init(machine, &scsi_intf);
|
|
||||||
|
|
||||||
sgi_mc_init(machine);
|
sgi_mc_init(machine);
|
||||||
|
|
||||||
state->m_HPC.nMiscStatus = 0;
|
state->m_HPC.nMiscStatus = 0;
|
||||||
@ -615,6 +616,7 @@ static MACHINE_CONFIG_START( ip204415, ip20_state )
|
|||||||
|
|
||||||
MCFG_SCC8530_ADD("scc", 7000000, line_cb_t())
|
MCFG_SCC8530_ADD("scc", 7000000, line_cb_t())
|
||||||
|
|
||||||
|
MCFG_WD33C93_ADD("wd33c93", scsi_intf);
|
||||||
MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_6)
|
MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_6)
|
||||||
|
|
||||||
MCFG_EEPROM_ADD("eeprom", eeprom_interface_93C56)
|
MCFG_EEPROM_ADD("eeprom", eeprom_interface_93C56)
|
||||||
|
@ -95,10 +95,12 @@ class ip22_state : public driver_device
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ip22_state(const machine_config &mconfig, device_type type, const char *tag)
|
ip22_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: driver_device(mconfig, type, tag) ,
|
: driver_device(mconfig, type, tag),
|
||||||
|
m_wd33c93(*this, "wd33c93"),
|
||||||
m_unkpbus0(*this, "unkpbus0"),
|
m_unkpbus0(*this, "unkpbus0"),
|
||||||
m_mainram(*this, "mainram") { }
|
m_mainram(*this, "mainram") { }
|
||||||
|
|
||||||
|
required_device<wd33c93_device> m_wd33c93;
|
||||||
required_shared_ptr<UINT32> m_unkpbus0;
|
required_shared_ptr<UINT32> m_unkpbus0;
|
||||||
required_shared_ptr<UINT32> m_mainram;
|
required_shared_ptr<UINT32> m_mainram;
|
||||||
RTC_t m_RTC;
|
RTC_t m_RTC;
|
||||||
@ -480,7 +482,7 @@ READ32_MEMBER(ip22_state::hpc3_hd0_r)
|
|||||||
// //verboselog((machine, 2, "HPC3 HD0 Status Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[0x17] );
|
// //verboselog((machine, 2, "HPC3 HD0 Status Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[0x17] );
|
||||||
if (ACCESSING_BITS_0_7)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
return wd33c93_r( &space, 0 );
|
return m_wd33c93->read( space, 0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -491,7 +493,7 @@ READ32_MEMBER(ip22_state::hpc3_hd0_r)
|
|||||||
// //verboselog((machine, 2, "HPC3 HD0 Register Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[nHPC3_hd0_register] );
|
// //verboselog((machine, 2, "HPC3 HD0 Register Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[nHPC3_hd0_register] );
|
||||||
if (ACCESSING_BITS_0_7)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
return wd33c93_r( &space, 1 );
|
return m_wd33c93->read( space, 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -515,7 +517,7 @@ WRITE32_MEMBER(ip22_state::hpc3_hd0_w)
|
|||||||
// //verboselog((machine, 2, "HPC3 HD0 Register Select Write: %08x\n", data );
|
// //verboselog((machine, 2, "HPC3 HD0 Register Select Write: %08x\n", data );
|
||||||
if (ACCESSING_BITS_0_7)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
wd33c93_w( &space, 0, data & 0x000000ff );
|
m_wd33c93->write( space, 0, data & 0x000000ff );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x0004/4:
|
case 0x0004/4:
|
||||||
@ -523,7 +525,7 @@ WRITE32_MEMBER(ip22_state::hpc3_hd0_w)
|
|||||||
// //verboselog((machine, 2, "HPC3 HD0 Register %d Write: %08x\n", nHPC3_hd0_register, data );
|
// //verboselog((machine, 2, "HPC3 HD0 Register %d Write: %08x\n", nHPC3_hd0_register, data );
|
||||||
if (ACCESSING_BITS_0_7)
|
if (ACCESSING_BITS_0_7)
|
||||||
{
|
{
|
||||||
wd33c93_w( &space, 1, data & 0x000000ff );
|
m_wd33c93->write( space, 1, data & 0x000000ff );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1261,9 +1263,9 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
|
|
||||||
if (state)
|
if (state)
|
||||||
{
|
{
|
||||||
if (wd33c93_get_dma_count())
|
if (drvstate->m_wd33c93->get_dma_count())
|
||||||
{
|
{
|
||||||
printf("wd33c93_get_dma_count() is %d\n", wd33c93_get_dma_count() );
|
printf("drvstate->m_wd33c93->get_dma_count() is %d\n", drvstate->m_wd33c93->get_dma_count() );
|
||||||
if (drvstate->m_HPC3.nSCSI0DMACtrl & HPC3_DMACTRL_ENABLE)
|
if (drvstate->m_HPC3.nSCSI0DMACtrl & HPC3_DMACTRL_ENABLE)
|
||||||
{
|
{
|
||||||
if (drvstate->m_HPC3.nSCSI0DMACtrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n");
|
if (drvstate->m_HPC3.nSCSI0DMACtrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n");
|
||||||
@ -1275,7 +1277,7 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
UINT32 wptr, tmpword;
|
UINT32 wptr, tmpword;
|
||||||
int words, dptr, twords;
|
int words, dptr, twords;
|
||||||
|
|
||||||
words = wd33c93_get_dma_count();
|
words = drvstate->m_wd33c93->get_dma_count();
|
||||||
words /= 4;
|
words /= 4;
|
||||||
|
|
||||||
wptr = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor);
|
wptr = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor);
|
||||||
@ -1289,7 +1291,7 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
if (words <= (512/4))
|
if (words <= (512/4))
|
||||||
{
|
{
|
||||||
// one-shot
|
// one-shot
|
||||||
//wd33c93_get_dma_data(wd33c93_get_dma_count(), drvstate->m_dma_buffer);
|
//drvstate->m_wd33c93->get_dma_data(drvstate->m_wd33c93->get_dma_count(), drvstate->m_dma_buffer);
|
||||||
|
|
||||||
while (words)
|
while (words)
|
||||||
{
|
{
|
||||||
@ -1315,14 +1317,14 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
words--;
|
words--;
|
||||||
}
|
}
|
||||||
|
|
||||||
words = wd33c93_get_dma_count();
|
words = drvstate->m_wd33c93->get_dma_count();
|
||||||
wd33c93_write_data(words, drvstate->m_dma_buffer);
|
drvstate->m_wd33c93->write_data(words, drvstate->m_dma_buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (words)
|
while (words)
|
||||||
{
|
{
|
||||||
//wd33c93_get_dma_data(512, drvstate->m_dma_buffer);
|
//drvstate->m_wd33c93->get_dma_data(512, drvstate->m_dma_buffer);
|
||||||
twords = 512/4;
|
twords = 512/4;
|
||||||
drvstate->m_HPC3.nSCSI0Descriptor += 512;
|
drvstate->m_HPC3.nSCSI0Descriptor += 512;
|
||||||
dptr = 0;
|
dptr = 0;
|
||||||
@ -1351,14 +1353,14 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
twords--;
|
twords--;
|
||||||
}
|
}
|
||||||
|
|
||||||
wd33c93_write_data(512, drvstate->m_dma_buffer);
|
drvstate->m_wd33c93->write_data(512, drvstate->m_dma_buffer);
|
||||||
|
|
||||||
words -= (512/4);
|
words -= (512/4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear DMA on the controller too
|
// clear DMA on the controller too
|
||||||
wd33c93_clear_dma();
|
drvstate->m_wd33c93->clear_dma();
|
||||||
#if 0
|
#if 0
|
||||||
UINT32 dptr, tmpword;
|
UINT32 dptr, tmpword;
|
||||||
UINT32 bc = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor + 4);
|
UINT32 bc = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor + 4);
|
||||||
@ -1399,10 +1401,10 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
length = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor+4) & 0x3fff;
|
length = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor+4) & 0x3fff;
|
||||||
wd33c93_write_data(length, drvstate->m_dma_buffer);
|
drvstate->m_wd33c93->write_data(length, drvstate->m_dma_buffer);
|
||||||
|
|
||||||
// clear DMA on the controller too
|
// clear DMA on the controller too
|
||||||
wd33c93_clear_dma();
|
drvstate->m_wd33c93->clear_dma();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1417,7 +1419,7 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
UINT32 wptr, tmpword;
|
UINT32 wptr, tmpword;
|
||||||
int words, sptr, twords;
|
int words, sptr, twords;
|
||||||
|
|
||||||
words = wd33c93_get_dma_count();
|
words = drvstate->m_wd33c93->get_dma_count();
|
||||||
words /= 4;
|
words /= 4;
|
||||||
|
|
||||||
wptr = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor);
|
wptr = space->read_dword(drvstate->m_HPC3.nSCSI0Descriptor);
|
||||||
@ -1430,7 +1432,7 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
if (words <= (1024/4))
|
if (words <= (1024/4))
|
||||||
{
|
{
|
||||||
// one-shot
|
// one-shot
|
||||||
wd33c93_get_dma_data(wd33c93_get_dma_count(), drvstate->m_dma_buffer);
|
drvstate->m_wd33c93->get_dma_data(drvstate->m_wd33c93->get_dma_count(), drvstate->m_dma_buffer);
|
||||||
|
|
||||||
while (words)
|
while (words)
|
||||||
{
|
{
|
||||||
@ -1453,7 +1455,7 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
{
|
{
|
||||||
while (words)
|
while (words)
|
||||||
{
|
{
|
||||||
wd33c93_get_dma_data(512, drvstate->m_dma_buffer);
|
drvstate->m_wd33c93->get_dma_data(512, drvstate->m_dma_buffer);
|
||||||
twords = 512/4;
|
twords = 512/4;
|
||||||
sptr = 0;
|
sptr = 0;
|
||||||
|
|
||||||
@ -1479,7 +1481,7 @@ static void scsi_irq(running_machine &machine, int state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clear DMA on the controller too
|
// clear DMA on the controller too
|
||||||
wd33c93_clear_dma();
|
drvstate->m_wd33c93->clear_dma();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1524,7 +1526,6 @@ static MACHINE_START( ip225015 )
|
|||||||
sgi_mc_init(machine);
|
sgi_mc_init(machine);
|
||||||
|
|
||||||
// SCSI init
|
// SCSI init
|
||||||
wd33c93_init(machine, &scsi_intf);
|
|
||||||
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ip225015_exit),&machine));
|
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(ip225015_exit),&machine));
|
||||||
|
|
||||||
machine.device<nvram_device>("nvram_user")->set_base(state->m_RTC.nUserRAM, 0x200);
|
machine.device<nvram_device>("nvram_user")->set_base(state->m_RTC.nUserRAM, 0x200);
|
||||||
@ -1691,6 +1692,7 @@ static MACHINE_CONFIG_START( ip225015, ip22_state )
|
|||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
|
||||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
|
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
|
||||||
|
|
||||||
|
MCFG_WD33C93_ADD("wd33c93", scsi_intf);
|
||||||
MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_4)
|
MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_4)
|
||||||
MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_1)
|
MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_1)
|
||||||
MACHINE_CONFIG_END
|
MACHINE_CONFIG_END
|
||||||
|
Loading…
Reference in New Issue
Block a user