diff --git a/src/emu/machine/smc91c9x.c b/src/emu/machine/smc91c9x.c index 7ae04e10723..fa34c7858e7 100644 --- a/src/emu/machine/smc91c9x.c +++ b/src/emu/machine/smc91c9x.c @@ -13,7 +13,6 @@ #include "emu.h" #include "smc91c9x.h" -#include "devlegcy.h" @@ -30,9 +29,6 @@ CONSTANTS ***************************************************************************/ -#define ETHER_BUFFER_SIZE (2048) -#define ETHER_RX_BUFFERS (4) - /* Ethernet registers - bank 0 */ #define EREG_TCR (0*8 + 0) #define EREG_EPH_STATUS (0*8 + 1) @@ -104,62 +100,118 @@ static const char *const ethernet_regname[64] = /*************************************************************************** - TYPE DEFINITIONS + DEVICE INTERFACE ***************************************************************************/ -struct smc91c9x_state +smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) + : device_t(mconfig, type, name, tag, owner, clock, shortname, source) { - device_t *device; - smc91c9x_irq_func irq_handler; +} - /* raw register data and masks */ - UINT16 reg[64]; - UINT16 regmask[64]; +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- - /* IRQ information */ - UINT8 irq_state; - - /* allocate information */ - UINT8 alloc_count; - - /* transmit/receive FIFOs */ - UINT8 fifo_count; - UINT8 rx[ETHER_BUFFER_SIZE * ETHER_RX_BUFFERS]; - UINT8 tx[ETHER_BUFFER_SIZE]; - - /* counters */ - UINT32 sent; - UINT32 recd; -}; - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -static void update_ethernet_irq(smc91c9x_state *smc); - - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - get_safe_token - makes sure that the passed - in device is, in fact, an IDE controller --------------------------------------------------*/ - -INLINE smc91c9x_state *get_safe_token(device_t *device) +void smc91c9x_device::device_config_complete() { - assert(device != NULL); - assert(device->type() == SMC91C94 || device->type() == SMC91C96); + // inherit a copy of the static data + const smc91c9x_interface *intf = reinterpret_cast(static_config()); + if (intf != NULL) + *static_cast(this) = *intf; - return (smc91c9x_state *)downcast(device)->token(); + // or initialize to defaults if none provided + else + { + memset(&m_interrupt, 0, sizeof(m_interrupt)); + } +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void smc91c9x_device::device_start() +{ + m_irq_handler = m_interrupt; + + /* register ide states */ + save_item(NAME(m_reg)); + save_item(NAME(m_regmask)); + save_item(NAME(m_irq_state)); + save_item(NAME(m_alloc_count)); + save_item(NAME(m_fifo_count)); + save_item(NAME(m_rx)); + save_item(NAME(m_tx)); + save_item(NAME(m_sent)); + save_item(NAME(m_recd)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void smc91c9x_device::device_reset() +{ + memset(m_reg, 0, sizeof(m_reg)); + memset(m_regmask, 0, sizeof(m_regmask)); + m_irq_state = 0; + m_alloc_count = 0; + m_fifo_count = 0; + m_sent = 0; + m_recd = 0; + + m_reg[EREG_TCR] = 0x0000; m_regmask[EREG_TCR] = 0x3d87; + m_reg[EREG_EPH_STATUS] = 0x0000; m_regmask[EREG_EPH_STATUS] = 0x0000; + m_reg[EREG_RCR] = 0x0000; m_regmask[EREG_RCR] = 0xc307; + m_reg[EREG_COUNTER] = 0x0000; m_regmask[EREG_COUNTER] = 0x0000; + m_reg[EREG_MIR] = 0x1212; m_regmask[EREG_MIR] = 0x0000; + m_reg[EREG_MCR] = 0x3300; m_regmask[EREG_MCR] = 0x00ff; + m_reg[EREG_BANK] = 0x3300; m_regmask[EREG_BANK] = 0x0007; + + m_reg[EREG_CONFIG] = 0x0030; m_regmask[EREG_CONFIG] = 0x17c6; + m_reg[EREG_BASE] = 0x1866; m_regmask[EREG_BASE] = 0xfffe; + m_reg[EREG_IA0_1] = 0x0000; m_regmask[EREG_IA0_1] = 0xffff; + m_reg[EREG_IA2_3] = 0x0000; m_regmask[EREG_IA2_3] = 0xffff; + m_reg[EREG_IA4_5] = 0x0000; m_regmask[EREG_IA4_5] = 0xffff; + m_reg[EREG_GENERAL_PURP] = 0x0000; m_regmask[EREG_GENERAL_PURP] = 0xffff; + m_reg[EREG_CONTROL] = 0x0100; m_regmask[EREG_CONTROL] = 0x68e7; + + m_reg[EREG_MMU_COMMAND] = 0x0000; m_regmask[EREG_MMU_COMMAND] = 0x00e7; + m_reg[EREG_PNR_ARR] = 0x8000; m_regmask[EREG_PNR_ARR] = 0x00ff; + m_reg[EREG_FIFO_PORTS] = 0x8080; m_regmask[EREG_FIFO_PORTS] = 0x0000; + m_reg[EREG_POINTER] = 0x0000; m_regmask[EREG_POINTER] = 0xf7ff; + m_reg[EREG_DATA_0] = 0x0000; m_regmask[EREG_DATA_0] = 0xffff; + m_reg[EREG_DATA_1] = 0x0000; m_regmask[EREG_DATA_1] = 0xffff; + m_reg[EREG_INTERRUPT] = 0x0004; m_regmask[EREG_INTERRUPT] = 0x7f00; + + m_reg[EREG_MT0_1] = 0x0000; m_regmask[EREG_MT0_1] = 0xffff; + m_reg[EREG_MT2_3] = 0x0000; m_regmask[EREG_MT2_3] = 0xffff; + m_reg[EREG_MT4_5] = 0x0000; m_regmask[EREG_MT4_5] = 0xffff; + m_reg[EREG_MT6_7] = 0x0000; m_regmask[EREG_MT6_7] = 0xffff; + m_reg[EREG_MGMT] = 0x3030; m_regmask[EREG_MGMT] = 0x0f0f; + m_reg[EREG_REVISION] = 0x3340; m_regmask[EREG_REVISION] = 0x0000; + m_reg[EREG_ERCV] = 0x331f; m_regmask[EREG_ERCV] = 0x009f; + + update_ethernet_irq(); } +const device_type SMC91C94 = &device_creator; + +smc91c94_device::smc91c94_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : smc91c9x_device(mconfig, SMC91C94, "SMC91C94", tag, owner, clock, "smc91c94", __FILE__) +{ +} + + +const device_type SMC91C96 = &device_creator; + +smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : smc91c9x_device(mconfig, SMC91C96, "SMC91C96", tag, owner, clock, "smc91c96", __FILE__) +{ +} /*************************************************************************** INTERNAL HELPERS @@ -169,15 +221,15 @@ INLINE smc91c9x_state *get_safe_token(device_t *device) update_ethernet_irq - update the IRQ state -------------------------------------------------*/ -static void update_ethernet_irq(smc91c9x_state *smc) +void smc91c9x_device::update_ethernet_irq() { - UINT8 mask = smc->reg[EREG_INTERRUPT] >> 8; - UINT8 state = smc->reg[EREG_INTERRUPT] & 0xff; + UINT8 mask = m_reg[EREG_INTERRUPT] >> 8; + UINT8 state = m_reg[EREG_INTERRUPT] & 0xff; /* update the IRQ state */ - smc->irq_state = ((mask & state) != 0); - if (smc->irq_handler != NULL) - (*smc->irq_handler)(smc->device, smc->irq_state ? ASSERT_LINE : CLEAR_LINE); + m_irq_state = ((mask & state) != 0); + if (m_irq_handler != NULL) + (*m_irq_handler)(this, m_irq_state ? ASSERT_LINE : CLEAR_LINE); } @@ -185,10 +237,10 @@ static void update_ethernet_irq(smc91c9x_state *smc) update_stats - draw statistics -------------------------------------------------*/ -static void update_stats(smc91c9x_state *smc) +void smc91c9x_device::update_stats() { if (DISPLAY_STATS) - popmessage("Sent:%d Rec'd:%d", smc->sent, smc->recd); + popmessage("Sent:%d Rec'd:%d", m_sent, m_recd); } @@ -196,31 +248,31 @@ static void update_stats(smc91c9x_state *smc) finish_enqueue - complete an enqueued packet -------------------------------------------------*/ -static void finish_enqueue(smc91c9x_state *smc, int param) +void smc91c9x_device::finish_enqueue(int param) { - int is_broadcast = (smc->tx[4] == 0xff && smc->tx[5] == 0xff && smc->tx[6] == 0xff && - smc->tx[7] == 0xff && smc->tx[8] == 0xff && smc->tx[9] == 0xff); + int is_broadcast = (m_tx[4] == 0xff && m_tx[5] == 0xff && m_tx[6] == 0xff && + m_tx[7] == 0xff && m_tx[8] == 0xff && m_tx[9] == 0xff); /* update the EPH register and stuff it in the first transmit word */ - smc->reg[EREG_EPH_STATUS] = 0x0001; + m_reg[EREG_EPH_STATUS] = 0x0001; if (is_broadcast) - smc->reg[EREG_EPH_STATUS] |= 0x0040; - smc->tx[0] = smc->reg[EREG_EPH_STATUS]; - smc->tx[1] = smc->reg[EREG_EPH_STATUS] >> 8; + m_reg[EREG_EPH_STATUS] |= 0x0040; + m_tx[0] = m_reg[EREG_EPH_STATUS]; + m_tx[1] = m_reg[EREG_EPH_STATUS] >> 8; /* signal a transmit interrupt and mark the transmit buffer empty */ - smc->reg[EREG_INTERRUPT] |= EINT_TX; - smc->reg[EREG_INTERRUPT] |= EINT_TX_EMPTY; - smc->reg[EREG_FIFO_PORTS] |= 0x0080; - smc->sent++; - update_stats(smc); + m_reg[EREG_INTERRUPT] |= EINT_TX; + m_reg[EREG_INTERRUPT] |= EINT_TX_EMPTY; + m_reg[EREG_FIFO_PORTS] |= 0x0080; + m_sent++; + update_stats(); /* loopback? */ - if (smc->reg[EREG_TCR] & 0x2002) - if (smc->fifo_count < ETHER_RX_BUFFERS) + if (m_reg[EREG_TCR] & 0x2002) + if (m_fifo_count < ETHER_RX_BUFFERS) { - int buffer_len = ((smc->tx[3] << 8) | smc->tx[2]) & 0x7ff; - UINT8 *packet = &smc->rx[smc->fifo_count++ * ETHER_BUFFER_SIZE]; + int buffer_len = ((m_tx[3] << 8) | m_tx[2]) & 0x7ff; + UINT8 *packet = &m_rx[m_fifo_count++ * ETHER_BUFFER_SIZE]; int packet_len; /* compute the packet length */ @@ -233,16 +285,16 @@ static void finish_enqueue(smc91c9x_state *smc, int param) packet[1] = 0x0000; packet[2] = buffer_len; packet[3] = buffer_len >> 8; - memcpy(&packet[4], &smc->tx[4], 6); - memcpy(&packet[10], &smc->tx[10], 6); - memcpy(&packet[16], &smc->tx[16], buffer_len - 16); + memcpy(&packet[4], &m_tx[4], 6); + memcpy(&packet[10], &m_tx[10], 6); + memcpy(&packet[16], &m_tx[16], buffer_len - 16); /* set the broadcast flag */ if (is_broadcast) packet[1] |= 0x40; /* pad? */ - if (smc->reg[EREG_TCR & 0x0080]) + if (m_reg[EREG_TCR & 0x0080]) if (packet_len < 64) { memset(&packet[buffer_len], 0, 64+6 - buffer_len); @@ -253,10 +305,10 @@ static void finish_enqueue(smc91c9x_state *smc, int param) } /* signal a receive */ - smc->reg[EREG_INTERRUPT] |= EINT_RCV; - smc->reg[EREG_FIFO_PORTS] &= ~0x8000; + m_reg[EREG_INTERRUPT] |= EINT_RCV; + m_reg[EREG_FIFO_PORTS] &= ~0x8000; } - update_ethernet_irq(smc); + update_ethernet_irq(); } @@ -264,7 +316,7 @@ static void finish_enqueue(smc91c9x_state *smc, int param) process_command - handle MMU commands -------------------------------------------------*/ -static void process_command(smc91c9x_state *smc, UINT16 data) +void smc91c9x_device::process_command(UINT16 data) { switch ((data >> 5) & 7) { @@ -276,10 +328,10 @@ static void process_command(smc91c9x_state *smc, UINT16 data) case ECMD_ALLOCATE: if (LOG_ETHERNET) logerror(" ALLOCATE MEMORY FOR TX (%d)\n", (data & 7)); - smc->reg[EREG_PNR_ARR] &= ~0xff00; - smc->reg[EREG_PNR_ARR] |= smc->alloc_count++ << 8; - smc->reg[EREG_INTERRUPT] |= 0x0008; - update_ethernet_irq(smc); + m_reg[EREG_PNR_ARR] &= ~0xff00; + m_reg[EREG_PNR_ARR] |= m_alloc_count++ << 8; + m_reg[EREG_INTERRUPT] |= 0x0008; + update_ethernet_irq(); break; case ECMD_RESET_MMU: @@ -295,20 +347,20 @@ static void process_command(smc91c9x_state *smc, UINT16 data) case ECMD_REMOVE_RELEASE: if (LOG_ETHERNET) logerror(" REMOVE AND RELEASE FRAME FROM RX FIFO\n"); - smc->reg[EREG_INTERRUPT] &= ~EINT_RCV; - if (smc->fifo_count > 0) - smc->fifo_count--; - if (smc->fifo_count > 0) + m_reg[EREG_INTERRUPT] &= ~EINT_RCV; + if (m_fifo_count > 0) + m_fifo_count--; + if (m_fifo_count > 0) { - memmove(&smc->rx[0], &smc->rx[ETHER_BUFFER_SIZE], smc->fifo_count * ETHER_BUFFER_SIZE); - smc->reg[EREG_INTERRUPT] |= EINT_RCV; - smc->reg[EREG_FIFO_PORTS] &= ~0x8000; + memmove(&m_rx[0], &m_rx[ETHER_BUFFER_SIZE], m_fifo_count * ETHER_BUFFER_SIZE); + m_reg[EREG_INTERRUPT] |= EINT_RCV; + m_reg[EREG_FIFO_PORTS] &= ~0x8000; } else - smc->reg[EREG_FIFO_PORTS] |= 0x8000; - update_ethernet_irq(smc); - smc->recd++; - update_stats(smc); + m_reg[EREG_FIFO_PORTS] |= 0x8000; + update_ethernet_irq(); + m_recd++; + update_stats(); break; case ECMD_RELEASE_PACKET: @@ -319,7 +371,7 @@ static void process_command(smc91c9x_state *smc, UINT16 data) case ECMD_ENQUEUE_PACKET: if (LOG_ETHERNET) logerror(" ENQUEUE TX PACKET\n"); - finish_enqueue(smc, 0); + finish_enqueue(0); break; case ECMD_RESET_FIFOS: @@ -327,7 +379,7 @@ static void process_command(smc91c9x_state *smc, UINT16 data) logerror(" RESET TX FIFOS\n"); break; } - smc->reg[EREG_MMU_COMMAND] &= ~0x0001; + m_reg[EREG_MMU_COMMAND] &= ~0x0001; } @@ -340,43 +392,42 @@ static void process_command(smc91c9x_state *smc, UINT16 data) smc91c9x_r - handle a read from the device -------------------------------------------------*/ -READ16_DEVICE_HANDLER( smc91c9x_r ) +READ16_MEMBER( smc91c9x_device::read ) { - smc91c9x_state *smc = get_safe_token(device); UINT32 result = ~0; /* determine the effective register */ offset %= 8; if (offset != EREG_BANK) - offset += 8 * (smc->reg[EREG_BANK] & 7); - result = smc->reg[offset]; + offset += 8 * (m_reg[EREG_BANK] & 7); + result = m_reg[offset]; switch (offset) { case EREG_PNR_ARR: if (ACCESSING_BITS_8_15) { - smc->reg[EREG_INTERRUPT] &= ~0x0008; - update_ethernet_irq(smc); + m_reg[EREG_INTERRUPT] &= ~0x0008; + update_ethernet_irq(); } break; case EREG_DATA_0: /* data register */ case EREG_DATA_1: /* data register */ { - UINT8 *buffer = (smc->reg[EREG_POINTER] & 0x8000) ? smc->rx : smc->tx; - int addr = smc->reg[EREG_POINTER] & 0x7ff; + UINT8 *buffer = (m_reg[EREG_POINTER] & 0x8000) ? m_rx : m_tx; + int addr = m_reg[EREG_POINTER] & 0x7ff; result = buffer[addr++]; if (ACCESSING_BITS_8_15) result |= buffer[addr++] << 8; - if (smc->reg[EREG_POINTER] & 0x4000) - smc->reg[EREG_POINTER] = (smc->reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff); + if (m_reg[EREG_POINTER] & 0x4000) + m_reg[EREG_POINTER] = (m_reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff); break; } } if (LOG_ETHERNET && offset != EREG_BANK) - logerror("%s:smc91c9x_r(%s) = %04X & %04X\n", device->machine().describe_context(), ethernet_regname[offset], result, mem_mask); + logerror("%s:smc91c9x_r(%s) = %04X & %04X\n", machine().describe_context(), ethernet_regname[offset], result, mem_mask); return result; } @@ -385,23 +436,22 @@ READ16_DEVICE_HANDLER( smc91c9x_r ) smc91c9x_w - handle a write to the device -------------------------------------------------*/ -WRITE16_DEVICE_HANDLER( smc91c9x_w ) +WRITE16_MEMBER( smc91c9x_device::write ) { - smc91c9x_state *smc = get_safe_token(device); -// UINT16 olddata; + // UINT16 olddata; /* determine the effective register */ offset %= 8; if (offset != EREG_BANK) - offset += 8 * (smc->reg[EREG_BANK] & 7); + offset += 8 * (m_reg[EREG_BANK] & 7); /* update the data generically */ -// olddata = smc->reg[offset]; - mem_mask &= smc->regmask[offset]; - COMBINE_DATA(&smc->reg[offset]); + // olddata = m_reg[offset]; + mem_mask &= m_regmask[offset]; + COMBINE_DATA(&m_reg[offset]); if (LOG_ETHERNET && offset != 7) - logerror("%s:smc91c9x_w(%s) = %04X & %04X\n", device->machine().describe_context(), ethernet_regname[offset], data, mem_mask); + logerror("%s:smc91c9x_w(%s) = %04X & %04X\n", machine().describe_context(), ethernet_regname[offset], data, mem_mask); /* handle it */ switch (offset) @@ -424,7 +474,7 @@ WRITE16_DEVICE_HANDLER( smc91c9x_w ) case EREG_RCR: /* receive control register */ if (LOG_ETHERNET) { - if (data & 0x8000) device->reset(); + if (data & 0x8000) reset(); if (data & 0x8000) logerror(" SOFT RST\n"); if (data & 0x4000) logerror(" FILT_CAR\n"); if (data & 0x0200) logerror(" STRIP CRC\n"); @@ -474,162 +524,25 @@ WRITE16_DEVICE_HANDLER( smc91c9x_w ) break; case EREG_MMU_COMMAND: /* command register */ - process_command(smc, data); + process_command(data); break; case EREG_DATA_0: /* data register */ case EREG_DATA_1: /* data register */ { - UINT8 *buffer = (smc->reg[EREG_POINTER] & 0x8000) ? smc->rx : smc->tx; - int addr = smc->reg[EREG_POINTER] & 0x7ff; + UINT8 *buffer = (m_reg[EREG_POINTER] & 0x8000) ? m_rx : m_tx; + int addr = m_reg[EREG_POINTER] & 0x7ff; buffer[addr++] = data; if (ACCESSING_BITS_8_15) buffer[addr++] = data >> 8; - if (smc->reg[EREG_POINTER] & 0x4000) - smc->reg[EREG_POINTER] = (smc->reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff); + if (m_reg[EREG_POINTER] & 0x4000) + m_reg[EREG_POINTER] = (m_reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff); break; } case EREG_INTERRUPT: - smc->reg[EREG_INTERRUPT] &= ~(data & 0x56); - update_ethernet_irq(smc); + m_reg[EREG_INTERRUPT] &= ~(data & 0x56); + update_ethernet_irq(); break; } } - - - -/*************************************************************************** - DEVICE INTERFACE -***************************************************************************/ - -/*------------------------------------------------- - device start callback --------------------------------------------------*/ - -static DEVICE_START( smc91c9x ) -{ - const smc91c9x_config *config = (const smc91c9x_config *)device->static_config(); - smc91c9x_state *smc = get_safe_token(device); - - /* validate some basic stuff */ - assert(device != NULL); - - /* store a pointer back to the device */ - smc->device = device; - smc->irq_handler = config->interrupt; - - /* register ide states */ - device->save_item(NAME(smc->reg)); - device->save_item(NAME(smc->regmask)); - device->save_item(NAME(smc->irq_state)); - device->save_item(NAME(smc->alloc_count)); - device->save_item(NAME(smc->fifo_count)); - device->save_item(NAME(smc->rx)); - device->save_item(NAME(smc->tx)); - device->save_item(NAME(smc->sent)); - device->save_item(NAME(smc->recd)); -} - - -/*------------------------------------------------- - device reset callback --------------------------------------------------*/ - -static DEVICE_RESET( smc91c9x ) -{ - smc91c9x_state *smc = get_safe_token(device); - - memset(smc->reg, 0, sizeof(smc->reg)); - memset(smc->regmask, 0, sizeof(smc->regmask)); - smc->irq_state = 0; - smc->alloc_count = 0; - smc->fifo_count = 0; - smc->sent = 0; - smc->recd = 0; - - smc->reg[EREG_TCR] = 0x0000; smc->regmask[EREG_TCR] = 0x3d87; - smc->reg[EREG_EPH_STATUS] = 0x0000; smc->regmask[EREG_EPH_STATUS] = 0x0000; - smc->reg[EREG_RCR] = 0x0000; smc->regmask[EREG_RCR] = 0xc307; - smc->reg[EREG_COUNTER] = 0x0000; smc->regmask[EREG_COUNTER] = 0x0000; - smc->reg[EREG_MIR] = 0x1212; smc->regmask[EREG_MIR] = 0x0000; - smc->reg[EREG_MCR] = 0x3300; smc->regmask[EREG_MCR] = 0x00ff; - smc->reg[EREG_BANK] = 0x3300; smc->regmask[EREG_BANK] = 0x0007; - - smc->reg[EREG_CONFIG] = 0x0030; smc->regmask[EREG_CONFIG] = 0x17c6; - smc->reg[EREG_BASE] = 0x1866; smc->regmask[EREG_BASE] = 0xfffe; - smc->reg[EREG_IA0_1] = 0x0000; smc->regmask[EREG_IA0_1] = 0xffff; - smc->reg[EREG_IA2_3] = 0x0000; smc->regmask[EREG_IA2_3] = 0xffff; - smc->reg[EREG_IA4_5] = 0x0000; smc->regmask[EREG_IA4_5] = 0xffff; - smc->reg[EREG_GENERAL_PURP] = 0x0000; smc->regmask[EREG_GENERAL_PURP] = 0xffff; - smc->reg[EREG_CONTROL] = 0x0100; smc->regmask[EREG_CONTROL] = 0x68e7; - - smc->reg[EREG_MMU_COMMAND] = 0x0000; smc->regmask[EREG_MMU_COMMAND] = 0x00e7; - smc->reg[EREG_PNR_ARR] = 0x8000; smc->regmask[EREG_PNR_ARR] = 0x00ff; - smc->reg[EREG_FIFO_PORTS] = 0x8080; smc->regmask[EREG_FIFO_PORTS] = 0x0000; - smc->reg[EREG_POINTER] = 0x0000; smc->regmask[EREG_POINTER] = 0xf7ff; - smc->reg[EREG_DATA_0] = 0x0000; smc->regmask[EREG_DATA_0] = 0xffff; - smc->reg[EREG_DATA_1] = 0x0000; smc->regmask[EREG_DATA_1] = 0xffff; - smc->reg[EREG_INTERRUPT] = 0x0004; smc->regmask[EREG_INTERRUPT] = 0x7f00; - - smc->reg[EREG_MT0_1] = 0x0000; smc->regmask[EREG_MT0_1] = 0xffff; - smc->reg[EREG_MT2_3] = 0x0000; smc->regmask[EREG_MT2_3] = 0xffff; - smc->reg[EREG_MT4_5] = 0x0000; smc->regmask[EREG_MT4_5] = 0xffff; - smc->reg[EREG_MT6_7] = 0x0000; smc->regmask[EREG_MT6_7] = 0xffff; - smc->reg[EREG_MGMT] = 0x3030; smc->regmask[EREG_MGMT] = 0x0f0f; - smc->reg[EREG_REVISION] = 0x3340; smc->regmask[EREG_REVISION] = 0x0000; - smc->reg[EREG_ERCV] = 0x331f; smc->regmask[EREG_ERCV] = 0x009f; - - update_ethernet_irq(smc); -} - - -smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) - : device_t(mconfig, type, name, tag, owner, clock, shortname, source) -{ - m_token = global_alloc_clear(smc91c9x_state); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void smc91c9x_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void smc91c9x_device::device_start() -{ - DEVICE_START_NAME( smc91c9x )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void smc91c9x_device::device_reset() -{ - DEVICE_RESET_NAME( smc91c9x )(this); -} - - -const device_type SMC91C94 = &device_creator; - -smc91c94_device::smc91c94_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : smc91c9x_device(mconfig, SMC91C94, "SMC91C94", tag, owner, clock, "smc91c94", __FILE__) -{ -} - - -const device_type SMC91C96 = &device_creator; - -smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : smc91c9x_device(mconfig, SMC91C96, "SMC91C96", tag, owner, clock, "smc91c96", __FILE__) -{ -} diff --git a/src/emu/machine/smc91c9x.h b/src/emu/machine/smc91c9x.h index df8df26de44..0295a339b2b 100644 --- a/src/emu/machine/smc91c9x.h +++ b/src/emu/machine/smc91c9x.h @@ -9,7 +9,8 @@ #ifndef __SMC91C9X__ #define __SMC91C9X__ - +#define ETHER_BUFFER_SIZE (2048) +#define ETHER_RX_BUFFERS (4) /*************************************************************************** TYPE DEFINITIONS @@ -18,52 +19,56 @@ typedef void (*smc91c9x_irq_func)(device_t *device, int state); -struct smc91c9x_config +struct smc91c9x_interface { - smc91c9x_irq_func interrupt; + smc91c9x_irq_func m_interrupt; }; - -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_SMC91C94_ADD(_tag, _config) \ - MCFG_DEVICE_ADD(_tag, SMC91C94, 0) \ - MCFG_DEVICE_CONFIG(_config) - -#define MCFG_SMC91C96_ADD(_tag, _config) \ - MCFG_DEVICE_ADD(_tag, SMC91C96, 0) \ - MCFG_DEVICE_CONFIG(_config) - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -DECLARE_READ16_DEVICE_HANDLER( smc91c9x_r ); -DECLARE_WRITE16_DEVICE_HANDLER( smc91c9x_w ); - - /* ----- device interface ----- */ -class smc91c9x_device : public device_t +class smc91c9x_device : public device_t, + public smc91c9x_interface { public: smc91c9x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); - ~smc91c9x_device() { global_free(m_token); } + ~smc91c9x_device() {} - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } + DECLARE_READ16_MEMBER( read ); + DECLARE_WRITE16_MEMBER( write ); + protected: // device-level overrides virtual void device_config_complete(); virtual void device_start(); virtual void device_reset(); + private: // internal state - void *m_token; + smc91c9x_irq_func m_irq_handler; + + /* raw register data and masks */ + UINT16 m_reg[64]; + UINT16 m_regmask[64]; + + /* IRQ information */ + UINT8 m_irq_state; + + /* allocate information */ + UINT8 m_alloc_count; + + /* transmit/receive FIFOs */ + UINT8 m_fifo_count; + UINT8 m_rx[ETHER_BUFFER_SIZE * ETHER_RX_BUFFERS]; + UINT8 m_tx[ETHER_BUFFER_SIZE]; + + /* counters */ + UINT32 m_sent; + UINT32 m_recd; + + void update_ethernet_irq(); + void update_stats(); + void finish_enqueue(int param); + void process_command(UINT16 data); }; @@ -83,5 +88,17 @@ public: extern const device_type SMC91C96; +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ + +#define MCFG_SMC91C94_ADD(_tag, _config) \ + MCFG_DEVICE_ADD(_tag, SMC91C94, 0) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_SMC91C96_ADD(_tag, _config) \ + MCFG_DEVICE_ADD(_tag, SMC91C96, 0) \ + MCFG_DEVICE_CONFIG(_config) + #endif diff --git a/src/mame/drivers/seattle.c b/src/mame/drivers/seattle.c index f0fcab680dd..ef4aec61de9 100644 --- a/src/mame/drivers/seattle.c +++ b/src/mame/drivers/seattle.c @@ -430,7 +430,8 @@ public: m_asic_reset(*this, "asic_reset"), m_rombase(*this, "rombase"), m_maincpu(*this, "maincpu"), - m_ide(*this, "ide") + m_ide(*this, "ide"), + m_ethernet(*this, "ethernet") { } @@ -440,6 +441,9 @@ public: required_shared_ptr m_interrupt_config; required_shared_ptr m_asic_reset; required_shared_ptr m_rombase; + required_device m_maincpu; + required_device m_ide; + optional_device m_ethernet; galileo_data m_galileo; widget_data m_widget; device_t *m_voodoo; @@ -517,8 +521,6 @@ public: void widget_reset(); void update_widget_irq(); void init_common(int ioasic, int serialnum, int yearoffs, int config); - required_device m_maincpu; - required_device m_ide; }; /************************************* @@ -1518,21 +1520,19 @@ WRITE32_MEMBER(seattle_state::carnevil_gun_w) READ32_MEMBER(seattle_state::ethernet_r) { - device_t *device = machine().device("ethernet"); if (!(offset & 8)) - return smc91c9x_r(device, space, offset & 7, mem_mask & 0xffff); + return m_ethernet->read(space, offset & 7, mem_mask & 0xffff); else - return smc91c9x_r(device, space, offset & 7, mem_mask & 0x00ff); + return m_ethernet->read(space, offset & 7, mem_mask & 0x00ff); } WRITE32_MEMBER(seattle_state::ethernet_w) { - device_t *device = machine().device("ethernet"); if (!(offset & 8)) - smc91c9x_w(device, space, offset & 7, data & 0xffff, mem_mask | 0xffff); + m_ethernet->write(space, offset & 7, data & 0xffff, mem_mask | 0xffff); else - smc91c9x_w(device, space, offset & 7, data & 0x00ff, mem_mask | 0x00ff); + m_ethernet->write(space, offset & 7, data & 0x00ff, mem_mask | 0x00ff); } @@ -1565,7 +1565,6 @@ void seattle_state::update_widget_irq() READ32_MEMBER(seattle_state::widget_r) { - device_t *device = machine().device("ethernet"); UINT32 result = ~0; switch (offset) @@ -1584,7 +1583,7 @@ READ32_MEMBER(seattle_state::widget_r) break; case WREG_ETHER_DATA: - result = smc91c9x_r(device, space, m_widget.ethernet_addr & 7, mem_mask & 0xffff); + result = m_ethernet->read(space, m_widget.ethernet_addr & 7, mem_mask & 0xffff); break; } @@ -1596,7 +1595,6 @@ READ32_MEMBER(seattle_state::widget_r) WRITE32_MEMBER(seattle_state::widget_w) { - device_t *device = machine().device("ethernet"); if (LOG_WIDGET) logerror("Widget write (%02X) = %08X & %08X\n", offset*4, data, mem_mask); @@ -1616,7 +1614,7 @@ WRITE32_MEMBER(seattle_state::widget_w) break; case WREG_ETHER_DATA: - smc91c9x_w(device, space, m_widget.ethernet_addr & 7, data & 0xffff, mem_mask & 0xffff); + m_ethernet->write(space, m_widget.ethernet_addr & 7, data & 0xffff, mem_mask & 0xffff); break; } } @@ -2569,7 +2567,7 @@ static MACHINE_CONFIG_DERIVED( seattle150, seattle_common ) MCFG_CPU_PROGRAM_MAP(seattle_map) MACHINE_CONFIG_END -static const smc91c9x_config ethernet_intf = +static const smc91c9x_interface ethernet_intf = { ethernet_interrupt }; diff --git a/src/mame/drivers/vegas.c b/src/mame/drivers/vegas.c index 773d221f3fc..c7d8b8fb616 100644 --- a/src/mame/drivers/vegas.c +++ b/src/mame/drivers/vegas.c @@ -1500,21 +1500,25 @@ static WRITE32_DEVICE_HANDLER( ide_bus_master32_w ) static READ32_DEVICE_HANDLER( ethernet_r ) { + smc91c94_device *ethernet = space.machine().device("ethernet"); + UINT32 result = 0; if (ACCESSING_BITS_0_15) - result |= smc91c9x_r(device, space, offset * 2 + 0, mem_mask); + result |= ethernet->read(space, offset * 2 + 0, mem_mask); if (ACCESSING_BITS_16_31) - result |= smc91c9x_r(device, space, offset * 2 + 1, mem_mask >> 16) << 16; + result |= ethernet->read(space, offset * 2 + 1, mem_mask >> 16) << 16; return result; } static WRITE32_DEVICE_HANDLER( ethernet_w ) { + smc91c94_device *ethernet = space.machine().device("ethernet"); + if (ACCESSING_BITS_0_15) - smc91c9x_w(device, space, offset * 2 + 0, data, mem_mask); + ethernet->write(space, offset * 2 + 0, data, mem_mask); if (ACCESSING_BITS_16_31) - smc91c9x_w(device, space, offset * 2 + 1, data >> 16, mem_mask >> 16); + ethernet->write(space, offset * 2 + 1, data >> 16, mem_mask >> 16); } @@ -2232,7 +2236,7 @@ static const mips3_config r5000_config = SYSTEM_CLOCK /* system clock rate */ }; -static const smc91c9x_config ethernet_intf = +static const smc91c9x_interface ethernet_intf = { ethernet_interrupt };