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.cpp127
1 files changed, 53 insertions, 74 deletions
diff --git a/src/devices/machine/i82586.cpp b/src/devices/machine/i82586.cpp
index e52c2ff8389..578d1a32979 100644
--- a/src/devices/machine/i82586.cpp
+++ b/src/devices/machine/i82586.cpp
@@ -31,9 +31,10 @@
#include "emu.h"
#include "i82586.h"
+
#include "hashing.h"
+#include "multibyte.h"
-#define LOG_GENERAL (1U << 0)
#define LOG_FRAMES (1U << 1)
#define LOG_FILTER (1U << 2)
#define LOG_CONFIG (1U << 3)
@@ -111,7 +112,7 @@ CFG_PARAMS[] =
i82586_base_device::i82586_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, endianness_t endian, u8 datawidth, u8 addrwidth)
: device_t(mconfig, type, tag, owner, clock)
, device_memory_interface(mconfig, *this)
- , device_network_interface(mconfig, *this, 10.0f)
+ , device_network_interface(mconfig, *this, 10)
, m_space_config("shared", endian, datawidth, addrwidth)
, m_out_irq(*this)
, m_cx(false)
@@ -120,6 +121,7 @@ i82586_base_device::i82586_base_device(const machine_config &mconfig, device_typ
, m_rnr(false)
, m_initialised(false)
, m_reset(false)
+ , m_irq(false)
, m_irq_assert(1)
, m_cu_state(CU_IDLE)
, m_ru_state(RU_IDLE)
@@ -162,10 +164,7 @@ void i82586_base_device::device_start()
{
m_space = &space(0);
- m_out_irq.resolve();
-
- m_cu_timer = timer_alloc(CU_TIMER);
- m_cu_timer->enable(false);
+ m_cu_timer = timer_alloc(FUNC(i82586_base_device::cu_execute), this);
save_item(NAME(m_cx));
save_item(NAME(m_fr));
@@ -173,6 +172,7 @@ void i82586_base_device::device_start()
save_item(NAME(m_rnr));
save_item(NAME(m_initialised));
save_item(NAME(m_reset));
+ save_item(NAME(m_irq));
save_item(NAME(m_cu_state));
save_item(NAME(m_ru_state));
@@ -189,7 +189,7 @@ void i82586_base_device::device_start()
void i82586_base_device::device_reset()
{
- m_cu_timer->enable(false);
+ m_cu_timer->reset();
m_cx = false;
m_fr = false;
@@ -202,16 +202,8 @@ void i82586_base_device::device_reset()
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)
-{
- switch (id)
- {
- case CU_TIMER:
- cu_execute();
- break;
- }
+ set_irq(false);
}
device_memory_interface::space_config_vector i82586_base_device::memory_space_config() const
@@ -221,7 +213,7 @@ device_memory_interface::space_config_vector i82586_base_device::memory_space_co
};
}
-WRITE_LINE_MEMBER(i82586_base_device::ca)
+void i82586_base_device::ca(int state)
{
LOG("channel attention %s (%s)\n", state ? "asserted" : "cleared", machine().describe_context());
@@ -235,7 +227,7 @@ WRITE_LINE_MEMBER(i82586_base_device::ca)
}
}
-WRITE_LINE_MEMBER(i82586_base_device::reset_w)
+void i82586_base_device::reset_w(int state)
{
LOG("reset %s (%s)\n", state ? "asserted" : "cleared", machine().describe_context());
@@ -337,12 +329,12 @@ void i82586_base_device::process_scb()
case CUC_RESUME:
m_cu_state = CU_ACTIVE;
- m_cu_timer->enable(true);
+ m_cu_timer->adjust(attotime::zero);
break;
case CUC_SUSPEND:
m_cu_state = CU_SUSPENDED;
- m_cu_timer->enable(false);
+ m_cu_timer->reset();
m_cna = true;
break;
@@ -407,7 +399,7 @@ void i82586_base_device::update_scb()
set_irq(m_cx || m_fr || m_cna || m_rnr);
}
-void i82586_base_device::cu_execute()
+TIMER_CALLBACK_MEMBER(i82586_base_device::cu_execute)
{
// fetch the command block command/status
const u32 cb_cs = m_space->read_dword(m_cba);
@@ -501,7 +493,7 @@ void i82586_base_device::cu_complete(const u16 status)
if (cb_cs & CB_S)
{
m_cu_state = CU_SUSPENDED;
- m_cu_timer->enable(false);
+ m_cu_timer->reset();
m_cna = true;
}
@@ -541,7 +533,7 @@ bool i82586_base_device::address_filter(u8 *mac)
}
// individual address
- if (!memcmp(mac, get_mac(), cfg_address_length()))
+ if (!memcmp(mac, &get_mac()[0], cfg_address_length()))
{
LOGMASKED(LOG_FILTER, "address_filter accepted: individual address match\n");
@@ -567,9 +559,16 @@ void i82586_base_device::set_irq(bool irq)
{
LOG("irq asserted\n");
+ // ensure an edge is generated if interrupt already asserted
+ if (m_irq)
+ m_out_irq(!m_irq_assert);
+
m_out_irq(m_irq_assert);
- m_out_irq(!m_irq_assert);
}
+ else if (m_irq)
+ m_out_irq(!m_irq_assert);
+
+ m_irq = irq;
}
u32 i82586_base_device::compute_crc(u8 *buf, int length, bool crc16)
@@ -822,7 +821,7 @@ void i82586_device::initialise()
bool i82586_device::cu_iasetup()
{
int len = cfg_address_length();
- char mac[6];
+ u8 mac[6];
u32 data;
if (len != 6)
@@ -833,14 +832,10 @@ bool i82586_device::cu_iasetup()
}
data = m_space->read_dword(m_cba + 4);
- mac[0] = (data >> 16) & 0xff;
- mac[1] = (data >> 24) & 0xff;
+ put_u16le(&mac[0], data >> 16);
data = m_space->read_dword(m_cba + 8);
- mac[2] = (data >> 0) & 0xff;
- mac[3] = (data >> 8) & 0xff;
- mac[4] = (data >> 16) & 0xff;
- mac[5] = (data >> 24) & 0xff;
+ put_u32le(&mac[2], data);
LOG("cu_iasetup individual address %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
set_mac(mac);
@@ -955,19 +950,17 @@ bool i82586_device::cu_transmit(u32 command)
// optionally insert source, destination address and length (14 bytes)
if (!cfg_no_src_add_ins())
{
- const char *mac = get_mac();
+ const std::array<u8, 6> &mac = get_mac();
u32 data;
// insert destination address (6 bytes)
data = m_space->read_dword(m_cba + 8);
- buf[length++] = (data >> 0) & 0xff;
- buf[length++] = (data >> 8) & 0xff;
- buf[length++] = (data >> 16) & 0xff;
- buf[length++] = (data >> 24) & 0xff;
+ put_u32le(&buf[length], data);
+ length += 4;
data = m_space->read_dword(m_cba + 12);
- buf[length++] = (data >> 0) & 0xff;
- buf[length++] = (data >> 8) & 0xff;
+ put_u16le(&buf[length], data & 0xffff);
+ length += 2;
// insert source address (6 bytes)
LOG("cu_transmit inserting source address %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@@ -976,8 +969,8 @@ bool i82586_device::cu_transmit(u32 command)
// insert length (2 bytes)
LOG("cu_transmit frame length 0x%04x\n", ((data >> 24) & 0xff) | ((data >> 16) & 0xff00));
- buf[length++] = (data >> 16) & 0xff;
- buf[length++] = (data >> 24) & 0xff;
+ put_u16le(&buf[length], data >> 16);
+ length += 2;
}
// check if there is no tbd
@@ -1008,10 +1001,8 @@ bool i82586_device::cu_transmit(u32 command)
u32 crc = compute_crc(buf, length, cfg_crc16());
// insert the fcs
- buf[length++] = (crc >> 0) & 0xff;
- buf[length++] = (crc >> 8) & 0xff;
- buf[length++] = (crc >> 16) & 0xff;
- buf[length++] = (crc >> 24) & 0xff;
+ put_u32le(&buf[length], crc);
+ length += 4;
}
if (cfg_loopback_mode())
@@ -1063,7 +1054,7 @@ bool i82586_device::cu_dump()
memcpy(&buf[0x00], &m_cfg_bytes[0], CFG_SIZE);
// individual address
- memcpy(&buf[0x0c], get_mac(), 6);
+ memcpy(&buf[0x0c], &get_mac()[0], 6);
// hash register
*(u64 *)&buf[0x24] = m_mac_multi;
@@ -1346,7 +1337,7 @@ bool i82596_device::cu_iasetup()
{
int len = cfg_address_length();
u32 data;
- char mac[6];
+ u8 mac[6];
if (len != 6)
{
@@ -1360,26 +1351,18 @@ bool i82596_device::cu_iasetup()
case MODE_82586:
case MODE_32SEGMENTED:
data = m_space->read_dword(m_cba + 4);
- mac[0] = (data >> 16) & 0xff;
- mac[1] = (data >> 24) & 0xff;
+ put_u16le(&mac[0], data >> 16);
data = m_space->read_dword(m_cba + 8);
- mac[2] = (data >> 0) & 0xff;
- mac[3] = (data >> 8) & 0xff;
- mac[4] = (data >> 16) & 0xff;
- mac[5] = (data >> 24) & 0xff;
+ put_u32le(&mac[2], data);
break;
case MODE_LINEAR:
data = m_space->read_dword(m_cba + 8);
- mac[0] = (data >> 0) & 0xff;
- mac[1] = (data >> 8) & 0xff;
- mac[2] = (data >> 16) & 0xff;
- mac[3] = (data >> 24) & 0xff;
+ put_u32le(&mac[0], data);
data = m_space->read_dword(m_cba + 12);
- mac[4] = (data >> 0) & 0xff;
- mac[5] = (data >> 8) & 0xff;
+ put_u16le(&mac[4], data & 0xffff);
break;
}
@@ -1601,19 +1584,17 @@ bool i82596_device::cu_transmit(u32 command)
// optionally insert destination, source and length (14 bytes)
if (!cfg_no_src_add_ins())
{
- const char *mac = get_mac();
+ const std::array<u8, 6> &mac = get_mac();
u32 data;
// insert destination address (6 bytes)
data = m_space->read_dword(m_cba + 12 + offset);
- buf[length++] = (data >> 0) & 0xff;
- buf[length++] = (data >> 8) & 0xff;
- buf[length++] = (data >> 16) & 0xff;
- buf[length++] = (data >> 24) & 0xff;
+ put_u32le(&buf[length], data);
+ length += 4;
data = m_space->read_dword(m_cba + 16 + offset);
- buf[length++] = (data >> 0) & 0xff;
- buf[length++] = (data >> 8) & 0xff;
+ put_u16le(&buf[length], data & 0xffff);
+ length += 2;
// insert source address (6 bytes)
LOG("cu_transmit inserting source address %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@@ -1622,8 +1603,8 @@ bool i82596_device::cu_transmit(u32 command)
// insert length from tcb (2 bytes)
LOG("cu_transmit frame length 0x%04x\n", ((data >> 24) & 0xff) | ((data >> 16) & 0xff00));
- buf[length++] = (data >> 16) & 0xff;
- buf[length++] = (data >> 24) & 0xff;
+ put_u16le(&buf[length], data >> 16);
+ length += 2;
// insert payload from tcb
LOG("cu_transmit inserting %d bytes from transmit command block\n", (tcb_count & TB_COUNT) - 8);
@@ -1680,10 +1661,8 @@ bool i82596_device::cu_transmit(u32 command)
u32 crc = compute_crc(buf, length, cfg_crc16());
// append the fcs
- buf[length++] = (crc >> 0) & 0xff;
- buf[length++] = (crc >> 8) & 0xff;
- buf[length++] = (crc >> 16) & 0xff;
- buf[length++] = (crc >> 24) & 0xff;
+ put_u32le(&buf[length], crc);
+ length += 4;
}
if (cfg_loopback_mode())
@@ -1740,7 +1719,7 @@ bool i82596_device::cu_dump()
memcpy(&buf[0x02], &m_cfg_bytes[2], 9);
// individual address
- memcpy(&buf[0x0c], get_mac(), 6);
+ memcpy(&buf[0x0c], &get_mac()[0], 6);
// hash register
*(u64 *)&buf[0x24] = m_mac_multi;
@@ -1751,7 +1730,7 @@ bool i82596_device::cu_dump()
memcpy(&buf[0x00], &m_cfg_bytes[2], 12);
// individual address
- memcpy(&buf[0x0e], get_mac(), 6);
+ memcpy(&buf[0x0e], &get_mac()[0], 6);
// hash register
*(u64 *)&buf[0x26] = m_mac_multi;
@@ -1848,7 +1827,7 @@ u16 i82596_device::ru_execute(u8 *buf, int length)
// TODO: increment alignment error counter
// set multicast status
- if (mode() != MODE_82586 && memcmp(buf, get_mac(), cfg_address_length()))
+ if (mode() != MODE_82586 && memcmp(buf, &get_mac()[0], cfg_address_length()))
status |= RFD_S_MULTICAST;
// fetch initial rbd address from rfd