mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
smc91c9x: Set link to be unconnected by default to keep warfa (vegas) from hanging. (nw)
This commit is contained in:
parent
6b44b4d3c4
commit
c62e5bc8ca
@ -108,6 +108,7 @@ static const char *const ethernet_regname[64] =
|
|||||||
smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||||
: device_t(mconfig, type, tag, owner, clock)
|
: device_t(mconfig, type, tag, owner, clock)
|
||||||
, m_irq_handler(*this)
|
, m_irq_handler(*this)
|
||||||
|
, m_link_unconnected(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,6 +119,8 @@ smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type
|
|||||||
void smc91c9x_device::device_start()
|
void smc91c9x_device::device_start()
|
||||||
{
|
{
|
||||||
m_irq_handler.resolve_safe();
|
m_irq_handler.resolve_safe();
|
||||||
|
// TX timer
|
||||||
|
m_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(smc91c9x_device::finish_enqueue), this));
|
||||||
|
|
||||||
/* register ide states */
|
/* register ide states */
|
||||||
save_item(NAME(m_reg));
|
save_item(NAME(m_reg));
|
||||||
@ -178,6 +181,7 @@ void smc91c9x_device::device_reset()
|
|||||||
m_reg[EREG_ERCV] = 0x331f; m_regmask[EREG_ERCV] = 0x009f;
|
m_reg[EREG_ERCV] = 0x331f; m_regmask[EREG_ERCV] = 0x009f;
|
||||||
|
|
||||||
update_ethernet_irq();
|
update_ethernet_irq();
|
||||||
|
m_tx_timer->adjust(attotime::never);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -211,9 +215,10 @@ void smc91c9x_device::update_ethernet_irq()
|
|||||||
|
|
||||||
/* update the IRQ state */
|
/* update the IRQ state */
|
||||||
m_irq_state = ((mask & state) != 0);
|
m_irq_state = ((mask & state) != 0);
|
||||||
if (!m_irq_handler.isnull())
|
if (!m_irq_handler.isnull()) {
|
||||||
m_irq_handler(m_irq_state ? ASSERT_LINE : CLEAR_LINE);
|
m_irq_handler(m_irq_state ? ASSERT_LINE : CLEAR_LINE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
@ -231,7 +236,7 @@ void smc91c9x_device::update_stats()
|
|||||||
finish_enqueue - complete an enqueued packet
|
finish_enqueue - complete an enqueued packet
|
||||||
-------------------------------------------------*/
|
-------------------------------------------------*/
|
||||||
|
|
||||||
void smc91c9x_device::finish_enqueue(int param)
|
TIMER_CALLBACK_MEMBER(smc91c9x_device::finish_enqueue)
|
||||||
{
|
{
|
||||||
int is_broadcast = (m_tx[4] == 0xff && m_tx[5] == 0xff && m_tx[6] == 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);
|
m_tx[7] == 0xff && m_tx[8] == 0xff && m_tx[9] == 0xff);
|
||||||
@ -251,7 +256,7 @@ void smc91c9x_device::finish_enqueue(int param)
|
|||||||
update_stats();
|
update_stats();
|
||||||
|
|
||||||
/* loopback? */
|
/* loopback? */
|
||||||
if (m_reg[EREG_TCR] & 0x2002)
|
if (m_reg[EREG_TCR] & 0x2002) {
|
||||||
if (m_fifo_count < ETHER_RX_BUFFERS)
|
if (m_fifo_count < ETHER_RX_BUFFERS)
|
||||||
{
|
{
|
||||||
int buffer_len = ((m_tx[3] << 8) | m_tx[2]) & 0x7ff;
|
int buffer_len = ((m_tx[3] << 8) | m_tx[2]) & 0x7ff;
|
||||||
@ -291,6 +296,25 @@ void smc91c9x_device::finish_enqueue(int param)
|
|||||||
m_reg[EREG_INTERRUPT] |= EINT_RCV;
|
m_reg[EREG_INTERRUPT] |= EINT_RCV;
|
||||||
m_reg[EREG_FIFO_PORTS] &= ~0x8000;
|
m_reg[EREG_FIFO_PORTS] &= ~0x8000;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (m_link_unconnected) {
|
||||||
|
// Set lost carrier
|
||||||
|
if (m_reg[EREG_TCR] & 0x0400) {
|
||||||
|
m_reg[EREG_EPH_STATUS] |= 0x400;
|
||||||
|
// Clear Tx Enable on error
|
||||||
|
m_reg[EREG_TCR] &= ~0x1;
|
||||||
|
}
|
||||||
|
// Set signal quality error
|
||||||
|
if (m_reg[EREG_TCR] & 0x1000) {
|
||||||
|
m_reg[EREG_EPH_STATUS] |= 0x20;
|
||||||
|
// Clear Tx Enable on error
|
||||||
|
m_reg[EREG_TCR] &= ~0x1;
|
||||||
|
}
|
||||||
|
// signal a no transmit
|
||||||
|
m_reg[EREG_INTERRUPT] &= ~EINT_TX;
|
||||||
|
// Set a ethernet phy status interrupt
|
||||||
|
m_reg[EREG_INTERRUPT] |= EINT_EPH;
|
||||||
|
}
|
||||||
update_ethernet_irq();
|
update_ethernet_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +378,8 @@ void smc91c9x_device::process_command(uint16_t data)
|
|||||||
case ECMD_ENQUEUE_PACKET:
|
case ECMD_ENQUEUE_PACKET:
|
||||||
if (LOG_ETHERNET)
|
if (LOG_ETHERNET)
|
||||||
logerror(" ENQUEUE TX PACKET\n");
|
logerror(" ENQUEUE TX PACKET\n");
|
||||||
finish_enqueue(0);
|
// Set some delay before tranmit ends
|
||||||
|
m_tx_timer->adjust(attotime::from_usec(100));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECMD_RESET_FIFOS:
|
case ECMD_RESET_FIFOS:
|
||||||
@ -440,6 +465,12 @@ WRITE16_MEMBER( smc91c9x_device::write )
|
|||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case EREG_TCR: /* transmit control register */
|
case EREG_TCR: /* transmit control register */
|
||||||
|
// Setting Tx Enable clears some status and interrupts
|
||||||
|
if (data & 0x1) {
|
||||||
|
m_reg[EREG_EPH_STATUS] &= ~0x420;
|
||||||
|
m_reg[EREG_INTERRUPT] &= ~EINT_EPH;
|
||||||
|
update_ethernet_irq();
|
||||||
|
}
|
||||||
if (LOG_ETHERNET)
|
if (LOG_ETHERNET)
|
||||||
{
|
{
|
||||||
if (data & 0x2000) logerror(" EPH LOOP\n");
|
if (data & 0x2000) logerror(" EPH LOOP\n");
|
||||||
|
@ -37,6 +37,9 @@ private:
|
|||||||
// internal state
|
// internal state
|
||||||
devcb_write_line m_irq_handler;
|
devcb_write_line m_irq_handler;
|
||||||
|
|
||||||
|
// link unconnected
|
||||||
|
bool m_link_unconnected;
|
||||||
|
|
||||||
/* raw register data and masks */
|
/* raw register data and masks */
|
||||||
uint16_t m_reg[64];
|
uint16_t m_reg[64];
|
||||||
uint16_t m_regmask[64];
|
uint16_t m_regmask[64];
|
||||||
@ -58,8 +61,10 @@ private:
|
|||||||
|
|
||||||
void update_ethernet_irq();
|
void update_ethernet_irq();
|
||||||
void update_stats();
|
void update_stats();
|
||||||
void finish_enqueue(int param);
|
TIMER_CALLBACK_MEMBER(finish_enqueue);
|
||||||
void process_command(uint16_t data);
|
void process_command(uint16_t data);
|
||||||
|
emu_timer* m_tx_timer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -602,6 +602,8 @@ WRITE8_MEMBER(vegas_state::sio_w)
|
|||||||
int index = offset >> 12;
|
int index = offset >> 12;
|
||||||
switch (index) {
|
switch (index) {
|
||||||
case 0:
|
case 0:
|
||||||
|
if (LOG_SIO)
|
||||||
|
logerror("sio_w: Reset Control offset: %08x index: %d data: %02X\n", offset, index, data);
|
||||||
// Reset Control: Bit 0=>Reset IOASIC, Bit 1=>Reset NSS Connection, Bit 2=>Reset SMC, Bit 3=>Reset VSYNC, Bit 4=>VSYNC Polarity
|
// Reset Control: Bit 0=>Reset IOASIC, Bit 1=>Reset NSS Connection, Bit 2=>Reset SMC, Bit 3=>Reset VSYNC, Bit 4=>VSYNC Polarity
|
||||||
m_sio_irq_clear = data;
|
m_sio_irq_clear = data;
|
||||||
|
|
||||||
@ -621,6 +623,14 @@ WRITE8_MEMBER(vegas_state::sio_w)
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// Interrupt Enable
|
// Interrupt Enable
|
||||||
|
// Bit 0 => SIO Watchdog
|
||||||
|
// Bit 1 => A/D Converter
|
||||||
|
// Bit 2 => IOASIC
|
||||||
|
// Bit 3 => NSS / Hi-Link
|
||||||
|
// Bit 4 => Ethernet
|
||||||
|
// Bit 5 => Vsync
|
||||||
|
if (LOG_SIO)
|
||||||
|
logerror("sio_w: Interrupt Enable offset: %08x index: %d data: %02X\n", offset, index, data);
|
||||||
m_sio_irq_enable = data;
|
m_sio_irq_enable = data;
|
||||||
update_sio_irqs();
|
update_sio_irqs();
|
||||||
break;
|
break;
|
||||||
@ -1247,6 +1257,7 @@ ADDRESS_MAP_END
|
|||||||
|
|
||||||
static ADDRESS_MAP_START(vegas_cs3_map, AS_PROGRAM, 32, vegas_state)
|
static ADDRESS_MAP_START(vegas_cs3_map, AS_PROGRAM, 32, vegas_state)
|
||||||
AM_RANGE(0x00000000, 0x00000003) AM_READWRITE(analog_port_r, analog_port_w)
|
AM_RANGE(0x00000000, 0x00000003) AM_READWRITE(analog_port_r, analog_port_w)
|
||||||
|
//AM_RANGE(0x00001000, 0x00001003) AM_READWRITE(lcd_r, lcd_w)
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
static ADDRESS_MAP_START(vegas_cs4_map, AS_PROGRAM, 32, vegas_state)
|
static ADDRESS_MAP_START(vegas_cs4_map, AS_PROGRAM, 32, vegas_state)
|
||||||
@ -1267,6 +1278,7 @@ static ADDRESS_MAP_START(vegas_cs6_map, AS_PROGRAM, 32, vegas_state)
|
|||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
static ADDRESS_MAP_START(vegas_cs7_map, AS_PROGRAM, 32, vegas_state)
|
static ADDRESS_MAP_START(vegas_cs7_map, AS_PROGRAM, 32, vegas_state)
|
||||||
|
//AM_RANGE(0x00000000, 0x00000003) AM_READWRITE8(nss_r, nss_w, 0xffffffff)
|
||||||
AM_RANGE(0x00001000, 0x0000100f) AM_READWRITE(ethernet_r, ethernet_w)
|
AM_RANGE(0x00001000, 0x0000100f) AM_READWRITE(ethernet_r, ethernet_w)
|
||||||
AM_RANGE(0x00005000, 0x00005003) AM_DEVWRITE("dcs", dcs_audio_device, dsio_idma_addr_w) // if (m_dcs_idma_cs == 7)
|
AM_RANGE(0x00005000, 0x00005003) AM_DEVWRITE("dcs", dcs_audio_device, dsio_idma_addr_w) // if (m_dcs_idma_cs == 7)
|
||||||
AM_RANGE(0x00007000, 0x00007003) AM_DEVREADWRITE("dcs", dcs_audio_device, dsio_idma_data_r, dsio_idma_data_w) // if (m_dcs_idma_cs == 7)
|
AM_RANGE(0x00007000, 0x00007003) AM_DEVREADWRITE("dcs", dcs_audio_device, dsio_idma_data_r, dsio_idma_data_w) // if (m_dcs_idma_cs == 7)
|
||||||
|
Loading…
Reference in New Issue
Block a user