am53cf96 is now a device (nw)

This commit is contained in:
smf- 2012-08-24 10:45:35 +00:00
parent 53539d0fba
commit d3d0443564
5 changed files with 146 additions and 117 deletions

View File

@ -13,50 +13,12 @@
#include "am53cf96.h"
#include "machine/scsidev.h"
static UINT8 scsi_regs[32], fifo[16], fptr = 0, xfer_state, last_id;
static const struct AM53CF96interface *intf;
static scsidev_device *devices[8]; // SCSI IDs 0-7
// 53CF96 register set
enum
READ8_MEMBER( am53cf96_device::read )
{
REG_XFERCNTLOW = 0, // read = current xfer count lo byte, write = set xfer count lo byte
REG_XFERCNTMID, // read = current xfer count mid byte, write = set xfer count mid byte
REG_FIFO, // read/write = FIFO
REG_COMMAND, // read/write = command
REG_STATUS, // read = status, write = destination SCSI ID (4)
REG_IRQSTATE, // read = IRQ status, write = timeout (5)
REG_INTSTATE, // read = internal state, write = sync xfer period (6)
REG_FIFOSTATE, // read = FIFO status, write = sync offset
REG_CTRL1, // read/write = control 1
REG_CLOCKFCTR, // clock factor (write only)
REG_TESTMODE, // test mode (write only)
REG_CTRL2, // read/write = control 2
REG_CTRL3, // read/write = control 3
REG_CTRL4, // read/write = control 4
REG_XFERCNTHI, // read = current xfer count hi byte, write = set xfer count hi byte
REG_DATAALIGN // data alignment (write only)
};
READ32_HANDLER( am53cf96_r )
{
int reg, shift, rv;
int rv;
static const int states[] = { 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 0 };
reg = offset * 2;
if (mem_mask == 0x000000ff)
{
shift = 0;
}
else
{
reg++;
shift = 16;
}
if (reg == REG_STATUS)
if (offset == REG_STATUS)
{
scsi_regs[REG_STATUS] &= ~0x7;
scsi_regs[REG_STATUS] |= states[xfer_state];
@ -66,17 +28,17 @@ READ32_HANDLER( am53cf96_r )
}
}
rv = scsi_regs[reg]<<shift;
rv = scsi_regs[offset];
if (reg == REG_FIFO)
if (offset == REG_FIFO)
{
// mame_printf_debug("53cf96: read FIFO PC=%x\n", cpu_get_pc(&space->device()));
// mame_printf_debug("53cf96: read FIFO PC=%x\n", cpu_get_pc(&space.device()));
return 0;
}
// logerror("53cf96: read reg %d = %x (PC=%x)\n", reg, rv>>shift, cpu_get_pc(&space->device()));
// logerror("53cf96: read reg %d = %x (PC=%x)\n", reg, rv>>shift, cpu_get_pc(&space.device()));
if (reg == REG_IRQSTATE)
if (offset == REG_IRQSTATE)
{
scsi_regs[REG_STATUS] &= ~0x80; // clear IRQ flag
}
@ -84,47 +46,33 @@ READ32_HANDLER( am53cf96_r )
return rv;
}
static TIMER_CALLBACK( am53cf96_irq )
void am53cf96_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
{
scsi_regs[REG_IRQSTATE] = 8; // indicate success
scsi_regs[REG_STATUS] |= 0x80; // indicate IRQ
intf->irq_callback(machine);
irq_callback(machine());
}
WRITE32_HANDLER( am53cf96_w )
WRITE8_MEMBER( am53cf96_device::write )
{
int reg, val/*, dma*/;
reg = offset * 2;
val = data;
if (mem_mask == 0x000000ff)
{
}
else
{
reg++;
val >>= 16;
}
val &= 0xff;
// logerror("53cf96: w %x to reg %d (ofs %02x data %08x mask %08x PC=%x)\n", val, reg, offset, data, mem_mask, cpu_get_pc(&space->device()));
// logerror("53cf96: w %x to reg %d (PC=%x)\n", data, offset, cpu_get_pc(&space.device()));
// if writing to the target ID, cache it off for later
if (reg == REG_STATUS)
if (offset == REG_STATUS)
{
last_id = val;
last_id = data;
}
if (reg == REG_XFERCNTLOW || reg == REG_XFERCNTMID || reg == REG_XFERCNTHI)
if (offset == REG_XFERCNTLOW || offset == REG_XFERCNTMID || offset == REG_XFERCNTHI)
{
scsi_regs[REG_STATUS] &= ~0x10; // clear CTZ bit
}
// FIFO
if (reg == REG_FIFO)
if (offset == REG_FIFO)
{
// mame_printf_debug("%02x to FIFO @ %02d\n", val, fptr);
fifo[fptr++] = val;
// mame_printf_debug("%02x to FIFO @ %02d\n", data, fptr);
fifo[fptr++] = data;
if (fptr > 15)
{
fptr = 15;
@ -132,11 +80,11 @@ WRITE32_HANDLER( am53cf96_w )
}
// command
if (reg == REG_COMMAND)
if (offset == REG_COMMAND)
{
//dma = (val & 0x80) ? 1 : 0;
//dma = (data & 0x80) ? 1 : 0;
fptr = 0;
switch (val & 0x7f)
switch (data & 0x7f)
{
case 0: // NOP
scsi_regs[REG_IRQSTATE] = 8; // indicate success
@ -145,7 +93,7 @@ WRITE32_HANDLER( am53cf96_w )
case 2: // reset device
scsi_regs[REG_IRQSTATE] = 8; // indicate success
logerror("53cf96: reset target ID = %d (PC = %x)\n", last_id, cpu_get_pc(&space->device()));
logerror("53cf96: reset target ID = %d (PC = %x)\n", last_id, cpu_get_pc(&space.device()));
if (devices[last_id])
{
devices[last_id]->reset();
@ -160,10 +108,10 @@ WRITE32_HANDLER( am53cf96_w )
case 3: // reset SCSI bus
scsi_regs[REG_INTSTATE] = 4; // command sent OK
xfer_state = 0;
space->machine().scheduler().timer_set( attotime::from_hz( 16384 ), FUNC(am53cf96_irq ));
m_transfer_timer->adjust( attotime::from_hz( 16384 ) );
break;
case 0x42: // select with ATN steps
space->machine().scheduler().timer_set( attotime::from_hz( 16384 ), FUNC(am53cf96_irq ));
m_transfer_timer->adjust( attotime::from_hz( 16384 ) );
if ((fifo[1] == 0) || (fifo[1] == 0x48) || (fifo[1] == 0x4b))
{
scsi_regs[REG_INTSTATE] = 6;
@ -173,7 +121,7 @@ WRITE32_HANDLER( am53cf96_w )
scsi_regs[REG_INTSTATE] = 4;
}
logerror("53cf96: command %x exec. target ID = %d (PC = %x)\n", fifo[1], last_id, cpu_get_pc(&space->device()));
logerror("53cf96: command %x exec. target ID = %d (PC = %x)\n", fifo[1], last_id, cpu_get_pc(&space.device()));
if (devices[last_id])
{
int length;
@ -193,48 +141,59 @@ WRITE32_HANDLER( am53cf96_w )
case 0x10: // information transfer (must not change xfer_state)
case 0x11: // second phase of information transfer
case 0x12: // message accepted
space->machine().scheduler().timer_set( attotime::from_hz( 16384 ), FUNC(am53cf96_irq ));
m_transfer_timer->adjust( attotime::from_hz( 16384 ) );
scsi_regs[REG_INTSTATE] = 6; // command sent OK
break;
default:
printf( "unsupported command %02x\n", val );
printf( "unsupported command %02x\n", data );
break;
}
}
// only update the register mirror if it's not a write-only reg
if (reg != REG_STATUS && reg != REG_INTSTATE && reg != REG_IRQSTATE && reg != REG_FIFOSTATE)
if (offset != REG_STATUS && offset != REG_INTSTATE && offset != REG_IRQSTATE && offset != REG_FIFOSTATE)
{
scsi_regs[reg] = val;
scsi_regs[offset] = data;
}
}
void am53cf96_init( running_machine &machine, const struct AM53CF96interface *interface )
am53cf96_device::am53cf96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, AM53CF96, "53CF96 SCSI", tag, owner, clock)
{
int i;
// save interface pointer for later
intf = interface;
}
void am53cf96_device::device_start()
{
memset(scsi_regs, 0, sizeof(scsi_regs));
memset(devices, 0, sizeof(devices));
// try to open the devices
for (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;
}
state_save_register_global_array(machine, scsi_regs);
state_save_register_global_array(machine, fifo);
state_save_register_global(machine, fptr);
state_save_register_global(machine, xfer_state);
state_save_register_global(machine, last_id);
fptr = 0;
xfer_state = 0;
save_item( NAME( scsi_regs ) );
save_item( NAME( fifo ) );
save_item( NAME( fptr ) );
save_item( NAME( xfer_state ) );
save_item( NAME( last_id ) );
m_transfer_timer = timer_alloc( TIMER_TRANSFER );
}
void am53cf96_device::static_set_interface(device_t &device, const AM53CF96interface &interface)
{
am53cf96_device &am53cf96 = downcast<am53cf96_device &>(device);
static_cast<AM53CF96interface &>(am53cf96) = interface;
}
// retrieve data from the SCSI controller
void am53cf96_read_data(int bytes, UINT8 *pData)
void am53cf96_device::dma_read_data(int bytes, UINT8 *pData)
{
scsi_regs[REG_STATUS] |= 0x10; // indicate DMA finished
@ -249,7 +208,7 @@ void am53cf96_read_data(int bytes, UINT8 *pData)
}
// write data to the SCSI controller
void am53cf96_write_data(int bytes, UINT8 *pData)
void am53cf96_device::dma_write_data(int bytes, UINT8 *pData)
{
// int i;
@ -264,3 +223,5 @@ void am53cf96_write_data(int bytes, UINT8 *pData)
logerror("53cf96: request for unknown device SCSI ID %d\n", last_id);
}
}
const device_type AM53CF96 = &device_creator<am53cf96_device>;

View File

@ -7,6 +7,7 @@
#define _AM53CF96_H_
#include "scsi.h"
#include "scsidev.h"
struct AM53CF96interface
{
@ -14,10 +15,68 @@ struct AM53CF96interface
void (*irq_callback)(running_machine &machine); /* irq callback */
};
extern void am53cf96_init( running_machine &machine, const struct AM53CF96interface *interface );
extern void am53cf96_read_data(int bytes, UINT8 *pData);
void am53cf96_write_data(int bytes, UINT8 *pData);
extern READ32_HANDLER( am53cf96_r );
extern WRITE32_HANDLER( am53cf96_w );
#define MCFG_AM53CF96_ADD( _tag, _interface ) \
MCFG_DEVICE_ADD( _tag, AM53CF96, 0 ) \
am53cf96_device::static_set_interface(*device, _interface);
// 53CF96 register set
enum
{
REG_XFERCNTLOW = 0, // read = current xfer count lo byte, write = set xfer count lo byte
REG_XFERCNTMID, // read = current xfer count mid byte, write = set xfer count mid byte
REG_FIFO, // read/write = FIFO
REG_COMMAND, // read/write = command
REG_STATUS, // read = status, write = destination SCSI ID (4)
REG_IRQSTATE, // read = IRQ status, write = timeout (5)
REG_INTSTATE, // read = internal state, write = sync xfer period (6)
REG_FIFOSTATE, // read = FIFO status, write = sync offset
REG_CTRL1, // read/write = control 1
REG_CLOCKFCTR, // clock factor (write only)
REG_TESTMODE, // test mode (write only)
REG_CTRL2, // read/write = control 2
REG_CTRL3, // read/write = control 3
REG_CTRL4, // read/write = control 4
REG_XFERCNTHI, // read = current xfer count hi byte, write = set xfer count hi byte
REG_DATAALIGN // data alignment (write only)
};
class am53cf96_device : public device_t,
public AM53CF96interface
{
public:
// construction/destruction
am53cf96_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 AM53CF96interface &interface);
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
void dma_read_data(int bytes, UINT8 *pData);
void dma_write_data(int bytes, UINT8 *pData);
protected:
// device-level overrides
virtual void device_start();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
static const device_timer_id TIMER_TRANSFER = 0;
scsidev_device *devices[8];
UINT8 scsi_regs[32];
UINT8 fifo[16];
UINT8 fptr;
UINT8 xfer_state;
UINT8 last_id;
emu_timer* m_transfer_timer;
};
// device type definition
extern const device_type AM53CF96;
#endif

View File

@ -177,7 +177,7 @@ READ32_MEMBER(konamigq_state::pcmram_r)
static ADDRESS_MAP_START( konamigq_map, AS_PROGRAM, 32, konamigq_state )
AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("share1") /* ram */
AM_RANGE(0x1f000000, 0x1f00001f) AM_READWRITE_LEGACY(am53cf96_r, am53cf96_w)
AM_RANGE(0x1f000000, 0x1f00001f) AM_DEVREADWRITE8("am53cf96", am53cf96_device, read, write, 0x00ff00ff)
AM_RANGE(0x1f100000, 0x1f10000f) AM_WRITE(soundr3k_w)
AM_RANGE(0x1f100010, 0x1f10001f) AM_READ(soundr3k_r)
AM_RANGE(0x1f180000, 0x1f180003) AM_WRITE(eeprom_w)
@ -260,6 +260,8 @@ static const k054539_interface k054539_config =
static void scsi_dma_read( konamigq_state *state, UINT32 n_address, INT32 n_size )
{
am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96");
UINT32 *p_n_psxram = state->m_p_n_psxram;
UINT8 *sector_buffer = state->m_sector_buffer;
int i;
@ -275,7 +277,7 @@ static void scsi_dma_read( konamigq_state *state, UINT32 n_address, INT32 n_size
{
n_this = n_size;
}
am53cf96_read_data( n_this * 4, sector_buffer );
am53cf96->dma_read_data( n_this * 4, sector_buffer );
n_size -= n_this;
i = 0;
@ -328,9 +330,6 @@ static MACHINE_START( konamigq )
{
konamigq_state *state = machine.driver_data<konamigq_state>();
/* init the scsi controller and hook up it's DMA */
am53cf96_init(machine, &scsi_intf);
state->save_pointer(NAME(state->m_p_n_pcmram), 0x380000);
state->save_item(NAME(state->m_sndto000));
state->save_item(NAME(state->m_sndtor3k));
@ -358,6 +357,8 @@ static MACHINE_CONFIG_START( konamigq, konamigq_state )
MCFG_EEPROM_93C46_ADD("eeprom")
MCFG_EEPROM_DATA(konamigq_def_eeprom, 128)
MCFG_AM53CF96_ADD("am53cf96", scsi_intf);
MCFG_SCSIDEV_ADD("disk", SCSIHD, SCSI_ID_0)
/* video hardware */

View File

@ -190,7 +190,7 @@ READ32_MEMBER(konamigv_state::mb89371_r)
static ADDRESS_MAP_START( konamigv_map, AS_PROGRAM, 32, konamigv_state )
AM_RANGE(0x00000000, 0x001fffff) AM_RAM AM_SHARE("share1") /* ram */
AM_RANGE(0x1f000000, 0x1f00001f) AM_READWRITE_LEGACY(am53cf96_r, am53cf96_w)
AM_RANGE(0x1f000000, 0x1f00001f) AM_DEVREADWRITE8("am53cf96", am53cf96_device, read, write, 0x00ff00ff)
AM_RANGE(0x1f100000, 0x1f100003) AM_READ_PORT("P1")
AM_RANGE(0x1f100004, 0x1f100007) AM_READ_PORT("P2")
AM_RANGE(0x1f100008, 0x1f10000b) AM_READ_PORT("P3_P4")
@ -209,6 +209,8 @@ ADDRESS_MAP_END
static void scsi_dma_read( konamigv_state *state, UINT32 n_address, INT32 n_size )
{
am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96");
UINT32 *p_n_psxram = state->m_p_n_psxram;
UINT8 *sector_buffer = state->m_sector_buffer;
int i;
@ -227,12 +229,12 @@ static void scsi_dma_read( konamigv_state *state, UINT32 n_address, INT32 n_size
if( n_this < 2048 / 4 )
{
/* non-READ commands */
am53cf96_read_data( n_this * 4, sector_buffer );
am53cf96->dma_read_data( n_this * 4, sector_buffer );
}
else
{
/* assume normal 2048 byte data for now */
am53cf96_read_data( 2048, sector_buffer );
am53cf96->dma_read_data( 2048, sector_buffer );
n_this = 2048 / 4;
}
n_size -= n_this;
@ -254,6 +256,8 @@ static void scsi_dma_read( konamigv_state *state, UINT32 n_address, INT32 n_size
static void scsi_dma_write( konamigv_state *state, UINT32 n_address, INT32 n_size )
{
am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96");
UINT32 *p_n_psxram = state->m_p_n_psxram;
UINT8 *sector_buffer = state->m_sector_buffer;
int i;
@ -283,7 +287,7 @@ static void scsi_dma_write( konamigv_state *state, UINT32 n_address, INT32 n_siz
n_this--;
}
am53cf96_write_data( n_this * 4, sector_buffer );
am53cf96->dma_write_data( n_this * 4, sector_buffer );
}
}
@ -309,9 +313,6 @@ static const struct AM53CF96interface scsi_intf =
DRIVER_INIT_MEMBER(konamigv_state,konamigv)
{
psx_driver_init(machine());
/* init the scsi controller and hook up it's DMA */
am53cf96_init(machine(), &scsi_intf);
}
static MACHINE_START( konamigv )
@ -356,6 +357,8 @@ static MACHINE_CONFIG_START( konamigv, konamigv_state )
MCFG_EEPROM_93C46_ADD("eeprom")
MCFG_AM53CF96_ADD("am53cf96", scsi_intf);
MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_4)
/* video hardware */

View File

@ -627,7 +627,7 @@ READ32_MEMBER(twinkle_state::shared_psx_r)
static ADDRESS_MAP_START( main_map, AS_PROGRAM, 32, twinkle_state )
AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("share1") /* ram */
AM_RANGE(0x1f000000, 0x1f0007ff) AM_READWRITE(shared_psx_r, shared_psx_w)
AM_RANGE(0x1f200000, 0x1f20001f) AM_READWRITE_LEGACY(am53cf96_r, am53cf96_w)
AM_RANGE(0x1f200000, 0x1f20001f) AM_DEVREADWRITE8("am53cf96", am53cf96_device, read, write, 0x00ff00ff)
AM_RANGE(0x1f20a01c, 0x1f20a01f) AM_WRITENOP /* scsi? */
AM_RANGE(0x1f210400, 0x1f2107ff) AM_READNOP
AM_RANGE(0x1f218000, 0x1f218003) AM_WRITE(watchdog_reset32_w) /* LTC1232 */
@ -768,6 +768,8 @@ ADDRESS_MAP_END
static void scsi_dma_read( twinkle_state *state, UINT32 n_address, INT32 n_size )
{
UINT32 *p_n_psxram = state->m_p_n_psxram;
am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96");
int i;
int n_this;
@ -784,12 +786,12 @@ static void scsi_dma_read( twinkle_state *state, UINT32 n_address, INT32 n_size
if( n_this < 2048 / 4 )
{
/* non-READ commands */
am53cf96_read_data( n_this * 4, state->m_sector_buffer );
am53cf96->dma_read_data( n_this * 4, state->m_sector_buffer );
}
else
{
/* assume normal 2048 byte data for now */
am53cf96_read_data( 2048, state->m_sector_buffer );
am53cf96->dma_read_data( 2048, state->m_sector_buffer );
n_this = 2048 / 4;
}
n_size -= n_this;
@ -812,6 +814,8 @@ static void scsi_dma_read( twinkle_state *state, UINT32 n_address, INT32 n_size
static void scsi_dma_write( twinkle_state *state, UINT32 n_address, INT32 n_size )
{
UINT32 *p_n_psxram = state->m_p_n_psxram;
am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96");
int i;
int n_this;
@ -839,7 +843,7 @@ static void scsi_dma_write( twinkle_state *state, UINT32 n_address, INT32 n_size
n_this--;
}
am53cf96_write_data( n_this * 4, state->m_sector_buffer );
am53cf96->dma_write_data( n_this * 4, state->m_sector_buffer );
}
}
@ -865,7 +869,6 @@ static const struct AM53CF96interface scsi_intf =
DRIVER_INIT_MEMBER(twinkle_state,twinkle)
{
psx_driver_init(machine());
am53cf96_init(machine(), &scsi_intf);
device_t *i2cmem = machine().device("security");
i2cmem_e0_write( i2cmem, 0 );
@ -917,6 +920,8 @@ static MACHINE_CONFIG_START( twinkle, twinkle_state )
MCFG_MACHINE_RESET( twinkle )
MCFG_I2CMEM_ADD("security",i2cmem_interface)
MCFG_AM53CF96_ADD("am53cf96", scsi_intf);
MCFG_SCSIDEV_ADD("cdrom0", SCSICD, SCSI_ID_4)
MCFG_IDE_CONTROLLER_ADD("ide", ide_interrupt, ide_devices, "hdd", NULL, true)