summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2018-11-21 17:09:24 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2018-11-21 17:10:01 +0700
commit0a12fa3d825c42c7438861c7236a486f12469c14 (patch)
tree3559ece6408493d898dccea65425088e2b559dd0
parent56f1d01eaaf0f517b686bbaecf8826a51e6ffe1a (diff)
am79c90: forced collision mode (nw)
Also fixed some error handling.
-rw-r--r--src/devices/machine/am79c90.cpp35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/devices/machine/am79c90.cpp b/src/devices/machine/am79c90.cpp
index 5f7e8c45aa6..4ea0fd2ba7f 100644
--- a/src/devices/machine/am79c90.cpp
+++ b/src/devices/machine/am79c90.cpp
@@ -337,8 +337,13 @@ void am7990_device_base::transmit()
else
{
// buffer error
+ m_tx_md[1] |= TMD1_ERR;
m_tx_md[3] |= TMD3_BUFF | TMD3_UFLO;
m_dma_out_cb(ring_address | 6, m_tx_md[3]);
+
+ // turn off the transmitter
+ m_csr[0] &= ~CSR0_TXON;
+ m_transmit_poll->enable(false);
break;
}
}
@@ -368,12 +373,22 @@ void am7990_device_base::transmit()
// handle internal loopback
if ((m_mode & MODE_LOOP) && (m_mode & MODE_INTL))
{
+ // forced collision
+ if (m_mode & MODE_COLL)
+ {
+ send_complete_cb(-1);
+ return;
+ }
+
int const fcs_length = add_fcs ? 4 : 0;
if ((length - fcs_length) < 8 || (length - fcs_length) > 32)
{
logerror("transmit invalid loopback packet length %d\n", length - fcs_length);
- length = 0;
+
+ // FIXME: don't know what to do, so just drop the packet
+ send_complete_cb(-2);
+ return;
}
memcpy(m_lb_buf, buf, length);
@@ -389,9 +404,23 @@ void am7990_device_base::send_complete_cb(int result)
{
u32 const ring_address = (m_tx_ring_base + (m_tx_ring_pos << 3)) & RING_ADDR_MASK;
- // FIXME: flag a loss of carrier on error
- if (!result)
+ // update tmd3 on error
+ switch (result)
+ {
+ case -2: // invalid internal loopback packet
+ m_tx_md[1] |= TMD1_ERR;
+ break;
+
+ case -1: // forced collision
+ m_tx_md[1] |= TMD1_ERR;
+ m_dma_out_cb(ring_address | 6, m_tx_md[3] | TMD3_RTRY);
+ break;
+
+ case 0: // failure to transmit (assume loss of carrier)
+ m_tx_md[1] |= TMD1_ERR;
m_dma_out_cb(ring_address | 6, m_tx_md[3] | TMD3_LCAR);
+ break;
+ }
// release the current descriptor
m_dma_out_cb(ring_address | 2, m_tx_md[1] & ~TMD1_OWN);