summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/i82586.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/i82586.cpp')
-rw-r--r--src/devices/machine/i82586.cpp124
1 files changed, 46 insertions, 78 deletions
diff --git a/src/devices/machine/i82586.cpp b/src/devices/machine/i82586.cpp
index 641793ceb94..3ecd092f0c1 100644
--- a/src/devices/machine/i82586.cpp
+++ b/src/devices/machine/i82586.cpp
@@ -42,9 +42,6 @@
#include "logmacro.h"
-// disable FCS insertion on transmit
-#define I82586_FCS 0
-
ALLOW_SAVE_TYPE(i82586_base_device::cu_state);
ALLOW_SAVE_TYPE(i82586_base_device::ru_state);
@@ -126,7 +123,6 @@ i82586_base_device::i82586_base_device(const machine_config &mconfig, device_typ
, m_cu_state(CU_IDLE)
, m_ru_state(RU_IDLE)
, m_scp_address(SCP_ADDRESS)
- , m_lb_length(0)
{
}
@@ -169,8 +165,6 @@ void i82586_base_device::device_start()
m_cu_timer = timer_alloc(CU_TIMER);
m_cu_timer->enable(false);
- m_ru_timer = timer_alloc(RU_TIMER);
- m_ru_timer->enable(false);
save_item(NAME(m_cx));
save_item(NAME(m_fr));
@@ -189,15 +183,11 @@ void i82586_base_device::device_start()
save_item(NAME(m_rfd));
save_item(NAME(m_mac_multi));
-
- save_item(NAME(m_lb_length));
- save_item(NAME(m_lb_buf));
}
void i82586_base_device::device_reset()
{
m_cu_timer->enable(false);
- m_ru_timer->enable(false);
m_cx = false;
m_fr = false;
@@ -209,7 +199,6 @@ void i82586_base_device::device_reset()
m_ru_state = RU_IDLE;
m_scp_address = SCP_ADDRESS;
- m_lb_length = 0;
}
void i82586_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@@ -219,16 +208,6 @@ void i82586_base_device::device_timer(emu_timer &timer, device_timer_id id, int
case CU_TIMER:
cu_execute();
break;
-
- case RU_TIMER:
- if (m_lb_length)
- {
- LOG("device_timer injecting loopback frame length %d\n", m_lb_length);
-
- recv_cb(m_lb_buf, m_lb_length);
- }
- m_lb_length = 0;
- break;
}
}
@@ -255,6 +234,10 @@ WRITE_LINE_MEMBER(i82586_base_device::ca)
int i82586_base_device::recv_start_cb(u8 *buf, int length)
{
+ // discard external packets in loopback mode
+ if (cfg_loopback_mode())
+ return 0;
+
switch (m_ru_state)
{
case RU_IDLE:
@@ -263,14 +246,7 @@ int i82586_base_device::recv_start_cb(u8 *buf, int length)
break;
case RU_READY:
- if (address_filter(buf))
- {
- LOG("recv_cb receiving frame length %d\n", length);
- dump_bytes(buf, length);
-
- return ru_execute(buf, length);
- }
- break;
+ return recv_start(buf, length);
default:
// no resources
@@ -281,6 +257,19 @@ int i82586_base_device::recv_start_cb(u8 *buf, int length)
return 0;
}
+int i82586_base_device::recv_start(u8 *buf, int length)
+{
+ if (address_filter(buf))
+ {
+ LOG("recv_start receiving frame length %d\n", length);
+ dump_bytes(buf, length);
+
+ return ru_execute(buf, length);
+ }
+
+ return 0;
+}
+
void i82586_base_device::recv_complete_cb(int result)
{
ru_complete(result);
@@ -977,9 +966,8 @@ bool i82586_device::cu_transmit(u32 command)
length += fetch_bytes(&buf[length], tb_address, tbd_count & TB_COUNT);
}
-#if I82586_FCS
// optionally compute/insert ethernet frame check sequence (4 bytes)
- if (!cfg_no_crc_insertion())
+ if (!cfg_no_crc_insertion() && !cfg_loopback_mode())
{
LOG("cu_transmit inserting frame check sequence\n");
@@ -991,21 +979,16 @@ bool i82586_device::cu_transmit(u32 command)
buf[length++] = (crc >> 16) & 0xff;
buf[length++] = (crc >> 24) & 0xff;
}
-#endif
- if (cfg_loopback_mode() != LOOPBACK_NONE)
+ if (cfg_loopback_mode())
{
LOG("cu_transmit loopback frame length %d\n", length);
- if (m_lb_length == 0)
- {
- memcpy(m_lb_buf, buf, length);
- m_lb_length = length;
+ int status = recv_start(buf, length);
+ if (status)
+ ru_complete(status);
- m_ru_timer->adjust(attotime::zero);
- }
- else
- LOG("cu_tranmit error: loopback buffer not empty\n");
+ cu_complete(CB_OK);
return true;
}
@@ -1089,7 +1072,7 @@ u16 i82586_device::ru_execute(u8 *buf, int length)
status |= RFD_S_SHORT;
// set crc status
- if (~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE)
+ if (!cfg_loopback_mode() && ~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE)
{
LOGMASKED(LOG_FRAMES, "ru_execute crc error computed 0x%08x stored 0x%08x\n",
compute_crc(buf, length - 4, cfg_crc16()), *(u32 *)&buf[length - 4]);
@@ -1656,9 +1639,8 @@ bool i82596_device::cu_transmit(u32 command)
length += fetch_bytes(&buf[length], tb_address, tbd_count & TB_COUNT);
}
-#if I82586_FCS
// optionally compute/insert ethernet frame check sequence (4 bytes)
- if (!cfg_no_crc_insertion() && !(command & CB_NC))
+ if (!cfg_no_crc_insertion() && !(command & CB_NC) && !cfg_loopback_mode())
{
LOG("cu_transmit inserting frame check sequence\n");
@@ -1670,23 +1652,16 @@ bool i82596_device::cu_transmit(u32 command)
buf[length++] = (crc >> 16) & 0xff;
buf[length++] = (crc >> 24) & 0xff;
}
-#endif
- if (cfg_loopback_mode() != LOOPBACK_NONE)
+ if (cfg_loopback_mode())
{
LOG("cu_transmit loopback frame length %d\n", length);
- if (m_lb_length == 0)
- {
- dump_bytes(buf, length);
-
- memcpy(m_lb_buf, buf, length);
- m_lb_length = length;
+ int status = recv_start(buf, length);
+ if (status)
+ ru_complete(status);
- m_ru_timer->adjust(attotime::zero);
- }
- else
- LOG("cu_tranmit error: loopback buffer not empty\n");
+ cu_complete(CB_OK);
return true;
}
@@ -1795,25 +1770,17 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
// offset into rfd/rbd for linear mode
int linear_offset = mode() == MODE_LINEAR ? 4 : 0;
- if (!cfg_crc_in_memory())
- {
- // compute and append fcs
- u32 crc = compute_crc(buf, length, false);
-
- // append the fcs
- buf[length++] = (crc >> 0) & 0xff;
- buf[length++] = (crc >> 8) & 0xff;
- buf[length++] = (crc >> 16) & 0xff;
- buf[length++] = (crc >> 24) & 0xff;
- }
-
// current buffer position and bytes remaining
int position = 0, remaining = length;
+ if (cfg_crc_in_memory())
+ remaining -= 4;
+
// set busy status
m_space->write_dword(m_rfd, rfd_cs | RFD_B);
- LOG("ru_execute receiving %d bytes using %s mode into rfd 0x%08x\n", length, (mode() == MODE_82586 ? "82586" : ((rfd_cs & RFD_SF) ? "flexible" : "simplified")), m_rfd);
+ LOG("ru_execute receiving %d bytes using %s mode into rfd 0x%08x\n",
+ remaining, (mode() == MODE_82586 ? "82586" : ((rfd_cs & RFD_SF) ? "flexible" : "simplified")), m_rfd);
// TODO: check length if configured, status bit 12
@@ -1830,7 +1797,7 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
}
// set crc status
- if (~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE)
+ if (!cfg_loopback_mode() && ~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE)
{
LOGMASKED(LOG_FRAMES, "ru_execute crc error computed 0x%08x stored 0x%08x\n",
compute_crc(buf, length - 4, cfg_crc16()), *(u32 *)&buf[length - 4]);
@@ -1861,30 +1828,31 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
u16 rfd_size = m_space->read_word(m_rfd + 10 + linear_offset, RB_SIZE);
// increment "no resources" counter
- if (rfd_size < length)
+ if (rfd_size < remaining)
m_space->write_dword(m_scb_address + 16 + linear_offset, m_space->read_dword(m_scb_address + 16 + linear_offset) + 1);
// truncate/capture the frame
- if (length <= rfd_size || cfg_save_bad_frames())
+ if (remaining <= rfd_size || cfg_save_bad_frames())
{
// compute stored length
- int actual = (rfd_size < length) ? rfd_size : length;
+ int actual = (rfd_size < remaining) ? rfd_size : remaining;
LOG("ru_execute storing %d bytes into rfd size %d\n", actual, rfd_size);
// store data in rfd
store_bytes(m_rfd + 12 + linear_offset, buf, actual);
- position += actual;
- remaining -= actual;
// store actual count, f and eof
m_space->write_word(m_rfd + 8 + linear_offset, actual | RB_F | RB_EOF);
// set frame received and truncated frame status
- status |= RFD_C | (actual < length ? RFD_S_TRUNCATED : 0);
+ status |= RFD_C | (actual < remaining ? RFD_S_TRUNCATED : 0);
+
+ position += actual;
+ remaining -= actual;
}
else
- LOG("ru_execute discarding %d byte frame exceeding rfd size %d\n", length, rfd_size);
+ LOG("ru_execute discarding %d byte frame exceeding rfd size %d\n", remaining, rfd_size);
}
else
{
@@ -1895,7 +1863,7 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
u16 rfd_size = m_space->read_word(m_rfd + 10 + linear_offset, RB_SIZE);
// compute stored length (from rfd_size)
- int actual = (rfd_size < length) ? rfd_size : length;
+ int actual = (rfd_size < remaining) ? rfd_size : remaining;
LOG("ru_execute storing %d bytes into rfd size %d\n", actual, rfd_size);