mirror of
https://github.com/holub/mame
synced 2025-07-03 09:06: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)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, 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()
|
||||
{
|
||||
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 */
|
||||
save_item(NAME(m_reg));
|
||||
@ -178,6 +181,7 @@ void smc91c9x_device::device_reset()
|
||||
m_reg[EREG_ERCV] = 0x331f; m_regmask[EREG_ERCV] = 0x009f;
|
||||
|
||||
update_ethernet_irq();
|
||||
m_tx_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
|
||||
@ -211,8 +215,9 @@ void smc91c9x_device::update_ethernet_irq()
|
||||
|
||||
/* update the IRQ state */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -231,7 +236,7 @@ void smc91c9x_device::update_stats()
|
||||
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 &&
|
||||
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();
|
||||
|
||||
/* loopback? */
|
||||
if (m_reg[EREG_TCR] & 0x2002)
|
||||
if (m_reg[EREG_TCR] & 0x2002) {
|
||||
if (m_fifo_count < ETHER_RX_BUFFERS)
|
||||
{
|
||||
int buffer_len = ((m_tx[3] << 8) | m_tx[2]) & 0x7ff;
|
||||
@ -280,9 +285,9 @@ void smc91c9x_device::finish_enqueue(int param)
|
||||
if (m_reg[EREG_TCR & 0x0080])
|
||||
if (packet_len < 64)
|
||||
{
|
||||
memset(&packet[buffer_len], 0, 64+6 - buffer_len);
|
||||
memset(&packet[buffer_len], 0, 64 + 6 - buffer_len);
|
||||
packet[buffer_len - 1] = 0;
|
||||
buffer_len = 64+6;
|
||||
buffer_len = 64 + 6;
|
||||
packet[2] = buffer_len;
|
||||
packet[3] = buffer_len >> 8;
|
||||
}
|
||||
@ -291,6 +296,25 @@ void smc91c9x_device::finish_enqueue(int param)
|
||||
m_reg[EREG_INTERRUPT] |= EINT_RCV;
|
||||
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();
|
||||
}
|
||||
|
||||
@ -354,7 +378,8 @@ void smc91c9x_device::process_command(uint16_t data)
|
||||
case ECMD_ENQUEUE_PACKET:
|
||||
if (LOG_ETHERNET)
|
||||
logerror(" ENQUEUE TX PACKET\n");
|
||||
finish_enqueue(0);
|
||||
// Set some delay before tranmit ends
|
||||
m_tx_timer->adjust(attotime::from_usec(100));
|
||||
break;
|
||||
|
||||
case ECMD_RESET_FIFOS:
|
||||
@ -440,6 +465,12 @@ WRITE16_MEMBER( smc91c9x_device::write )
|
||||
switch (offset)
|
||||
{
|
||||
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 (data & 0x2000) logerror(" EPH LOOP\n");
|
||||
|
@ -37,6 +37,9 @@ private:
|
||||
// internal state
|
||||
devcb_write_line m_irq_handler;
|
||||
|
||||
// link unconnected
|
||||
bool m_link_unconnected;
|
||||
|
||||
/* raw register data and masks */
|
||||
uint16_t m_reg[64];
|
||||
uint16_t m_regmask[64];
|
||||
@ -58,8 +61,10 @@ private:
|
||||
|
||||
void update_ethernet_irq();
|
||||
void update_stats();
|
||||
void finish_enqueue(int param);
|
||||
TIMER_CALLBACK_MEMBER(finish_enqueue);
|
||||
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;
|
||||
switch (index) {
|
||||
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
|
||||
m_sio_irq_clear = data;
|
||||
|
||||
@ -621,6 +623,14 @@ WRITE8_MEMBER(vegas_state::sio_w)
|
||||
break;
|
||||
case 1:
|
||||
// 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;
|
||||
update_sio_irqs();
|
||||
break;
|
||||
@ -1247,6 +1257,7 @@ ADDRESS_MAP_END
|
||||
|
||||
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(0x00001000, 0x00001003) AM_READWRITE(lcd_r, lcd_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
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
|
||||
|
||||
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(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)
|
||||
|
Loading…
Reference in New Issue
Block a user