From d3d04435641f3cd0a472343e6da39de069410ea8 Mon Sep 17 00:00:00 2001 From: smf- Date: Fri, 24 Aug 2012 10:45:35 +0000 Subject: [PATCH] am53cf96 is now a device (nw) --- src/emu/machine/am53cf96.c | 151 +++++++++++++----------------------- src/emu/machine/am53cf96.h | 69 ++++++++++++++-- src/mame/drivers/konamigq.c | 11 +-- src/mame/drivers/konamigv.c | 17 ++-- src/mame/drivers/twinkle.c | 15 ++-- 5 files changed, 146 insertions(+), 117 deletions(-) diff --git a/src/emu/machine/am53cf96.c b/src/emu/machine/am53cf96.c index bd92eaefe1d..586529f7190 100644 --- a/src/emu/machine/am53cf96.c +++ b/src/emu/machine/am53cf96.c @@ -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]<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( interface->scsidevs->devices[i].tag ); + scsidev_device *device = machine().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(device); + static_cast(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; diff --git a/src/emu/machine/am53cf96.h b/src/emu/machine/am53cf96.h index d92d140009d..695f48bfd8b 100644 --- a/src/emu/machine/am53cf96.h +++ b/src/emu/machine/am53cf96.h @@ -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 diff --git a/src/mame/drivers/konamigq.c b/src/mame/drivers/konamigq.c index 3bad8403c29..851502201dc 100644 --- a/src/mame/drivers/konamigq.c +++ b/src/mame/drivers/konamigq.c @@ -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"); + 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(); - /* 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 */ diff --git a/src/mame/drivers/konamigv.c b/src/mame/drivers/konamigv.c index 8c053cc5a03..0f23b25d890 100644 --- a/src/mame/drivers/konamigv.c +++ b/src/mame/drivers/konamigv.c @@ -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"); + 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"); + 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 */ diff --git a/src/mame/drivers/twinkle.c b/src/mame/drivers/twinkle.c index 44e15d58076..da7f86be1c1 100644 --- a/src/mame/drivers/twinkle.c +++ b/src/mame/drivers/twinkle.c @@ -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"); + 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"); + 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)