summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2021-06-01 19:27:34 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2021-06-01 19:27:34 +0700
commit743dfcf9bd1757d3bdae50a04158605dff502109 (patch)
tree784cccba138eabc0cb9b87f2a6bb8bf05f5b82c1
parentccf73700ae8095276cbee950f56b4b62b85e3146 (diff)
i82586: various fixes
* send fcs in loopback mode * don't store fcs in memory * don't consume descriptors for bad frames
-rw-r--r--src/devices/machine/i82586.cpp91
1 files changed, 48 insertions, 43 deletions
diff --git a/src/devices/machine/i82586.cpp b/src/devices/machine/i82586.cpp
index 4cad2244d35..e52c2ff8389 100644
--- a/src/devices/machine/i82586.cpp
+++ b/src/devices/machine/i82586.cpp
@@ -96,7 +96,7 @@ CFG_PARAMS[] =
{ "number of retries", "maximum number of retries", 15, 7, 0xf0, 4, true },
{ "no crc insertion", "crc appended to frame", 0, 8, 0x10, 4, false },
{ "prefetch bit in rbd", "disabled (valid only in new modes)", 0, 0, 0x80, 7, false },
- { "preamble length", "bytes", 7, 3, 0x30, 4, true },
+ { "preamble length", "2^(n+1) bytes", 2, 3, 0x30, 4, true },
{ "preamble until crs", "disabled", 1, 11, 0x01, 0, false },
{ "promiscuous mode", "address filter on", 0, 8, 0x01, 0, false },
{ "padding", "no padding", 0, 8, 0x80, 7, false },
@@ -201,6 +201,7 @@ void i82586_base_device::device_reset()
m_ru_state = RU_IDLE;
m_scp_address = SCP_ADDRESS;
+ m_mac_multi = 0;
}
void i82586_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@@ -1000,7 +1001,7 @@ bool i82586_device::cu_transmit(u32 command)
}
// optionally compute/insert ethernet frame check sequence (4 bytes)
- if (!cfg_no_crc_insertion() && !cfg_loopback_mode())
+ if (!cfg_no_crc_insertion())
{
LOG("cu_transmit inserting frame check sequence\n");
@@ -1092,8 +1093,8 @@ u16 i82586_device::ru_execute(u8 *buf, int length)
u32 rfd_cs = m_space->read_dword(m_rfd);
u16 status = 0;
- // current buffer position and bytes remaining
- int position = 0, remaining = length;
+ // current buffer position and bytes remaining (excluding fcs)
+ int position = 0, remaining = length - 4;
// set busy status
m_space->write_dword(m_rfd, rfd_cs | RFD_B);
@@ -1105,7 +1106,7 @@ u16 i82586_device::ru_execute(u8 *buf, int length)
status |= RFD_S_SHORT;
// set crc status
- if (!cfg_loopback_mode() && ~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE)
+ if (~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]);
@@ -1187,18 +1188,18 @@ u16 i82586_device::ru_execute(u8 *buf, int length)
void i82586_device::ru_complete(const u16 status)
{
- if (status & RFD_OK)
- LOG("ru_complete frame received without error\n");
- else
- LOG("ru_complete frame received with errors status 0x%04x\n", status);
-
- // update receive frame descriptor status
- u32 rfd_cs = m_space->read_dword(m_rfd);
- m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status);
-
// if we received without error, or we're saving bad frames, advance to the next rfd
if ((status & RFD_OK) || cfg_save_bad_frames())
{
+ if (status & RFD_OK)
+ LOG("ru_complete frame received without error\n");
+ else
+ LOG("ru_complete frame received with errors status 0x%04x\n", status);
+
+ // update receive frame descriptor status
+ u32 rfd_cs = m_space->read_dword(m_rfd);
+ m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status);
+
if (!(rfd_cs & RFD_EL))
{
// advance to next rfd
@@ -1216,17 +1217,19 @@ void i82586_device::ru_complete(const u16 status)
// set frame received status
m_fr = true;
- }
- // suspend on completion
- if (rfd_cs & RFD_S)
- {
- m_ru_state = RU_SUSPENDED;
- m_rnr = true;
- }
+ // suspend on completion
+ if (rfd_cs & RFD_S)
+ {
+ m_ru_state = RU_SUSPENDED;
+ m_rnr = true;
+ }
- static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY" };
- LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]);
+ static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY" };
+ LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]);
+ }
+ else
+ LOG("ru_complete discarded frame with errors status 0x%04x\n", status);
}
u32 i82586_device::address(u32 base, int offset, int address, u16 empty)
@@ -1827,7 +1830,7 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
}
// set crc status
- if (!cfg_loopback_mode() && ~compute_crc(buf, length, cfg_crc16()) != FCS_RESIDUE)
+ if (~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]);
@@ -1970,18 +1973,18 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
void i82596_device::ru_complete(const u16 status)
{
- if (status & RFD_OK)
- LOG("ru_complete frame received without error\n");
- else
- LOG("ru_complete frame received with errors status 0x%04x\n", status);
-
- // store status
- const u32 rfd_cs = m_space->read_dword(m_rfd);
- m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status);
-
// if we received without error, or we're saving bad frames, advance to the next rfd
- if ((rfd_cs & RFD_OK) || cfg_save_bad_frames())
+ if ((status & RFD_OK) || cfg_save_bad_frames())
{
+ if (status & RFD_OK)
+ LOG("ru_complete frame received without error\n");
+ else
+ LOG("ru_complete frame received with errors status 0x%04x\n", status);
+
+ // update receive frame descriptor status
+ const u32 rfd_cs = m_space->read_dword(m_rfd);
+ m_space->write_dword(m_rfd, (rfd_cs & ~0xffffU) | status);
+
if (!(rfd_cs & RFD_EL))
{
// advance to next rfd
@@ -2004,17 +2007,19 @@ void i82596_device::ru_complete(const u16 status)
// set frame received status
m_fr = true;
- }
- // suspend on completion
- if (rfd_cs & RFD_S)
- {
- m_ru_state = RU_SUSPENDED;
- m_rnr = true;
- }
+ // suspend on completion
+ if (rfd_cs & RFD_S)
+ {
+ m_ru_state = RU_SUSPENDED;
+ m_rnr = true;
+ }
- static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY", nullptr, nullptr, nullptr, nullptr, nullptr, "NO RESOURCES (RFD)", nullptr, "NO RESOURCES (RBD)" };
- LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]);
+ static const char *const RU_STATE_NAME[] = { "IDLE", "SUSPENDED", "NO RESOURCES", nullptr, "READY", nullptr, nullptr, nullptr, nullptr, nullptr, "NO RESOURCES (RFD)", nullptr, "NO RESOURCES (RBD)" };
+ LOG("ru_complete complete state %s\n", RU_STATE_NAME[m_ru_state]);
+ }
+ else
+ LOG("ru_complete discarded frame with errors status 0x%04x\n", status);
}
u32 i82596_device::address(u32 base, int offset, int address, u16 empty)