dinetwork: Add loopback control (nw)

This commit is contained in:
AJR 2019-05-26 22:14:18 -04:00
parent b956b41125
commit 2090f71585
3 changed files with 46 additions and 6 deletions

View File

@ -10,6 +10,7 @@ device_network_interface::device_network_interface(const machine_config &mconfig
m_bandwidth = bandwidth;
set_mac("\0\0\0\0\0\0");
m_intf = 0;
m_loopback_control = false;
}
device_network_interface::~device_network_interface()
@ -22,14 +23,30 @@ void device_network_interface::interface_pre_start()
m_recv_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_network_interface::recv_complete), this));
}
int device_network_interface::send(u8 *buf, int len) const
void device_network_interface::interface_post_start()
{
device().save_item(NAME(m_loopback_control));
}
int device_network_interface::send(u8 *buf, int len)
{
// TODO: enable this check when other devices implement delayed transmit
//assert_always(!m_send_timer->enabled(), "attempted to transmit while transmit already in progress");
int result = 0;
if (m_dev)
if (m_loopback_control)
{
// loop data back to receiver
result = recv_start_cb(buf, len);
if (result)
{
// schedule receive complete callback
m_recv_timer->adjust(attotime::from_ticks(len, m_bandwidth * 1'000'000 / 8), result);
}
}
else if (m_dev)
{
// send the data
result = m_dev->send(buf, len);
@ -50,8 +67,11 @@ void device_network_interface::recv_cb(u8 *buf, int len)
{
assert_always(!m_recv_timer->enabled(), "attempted to receive while receive already in progress");
int result = 0;
// process the received data
int result = recv_start_cb(buf, len);
if (!m_loopback_control)
result = recv_start_cb(buf, len);
if (result)
{
@ -69,7 +89,7 @@ TIMER_CALLBACK_MEMBER(device_network_interface::recv_complete)
recv_complete_cb(param);
// start receiving data from the network again
if (m_dev)
if (m_dev && !m_loopback_control)
m_dev->start();
}
@ -96,3 +116,19 @@ void device_network_interface::set_interface(int id)
}
m_intf = id;
}
void device_network_interface::set_loopback(bool loopback)
{
if (m_loopback_control == loopback)
return;
m_loopback_control = loopback;
if (m_dev)
{
if (loopback)
m_dev->stop();
else if (!m_recv_timer->enabled())
m_dev->start();
}
}

View File

@ -12,16 +12,18 @@ public:
virtual ~device_network_interface();
void interface_pre_start() override;
void interface_post_start() override;
void set_interface(int id);
void set_promisc(bool promisc);
void set_mac(const char *mac);
void set_loopback(bool loopback);
const char *get_mac() const { return m_mac; }
bool get_promisc() const { return m_promisc; }
int get_interface() const { return m_intf; }
int send(u8 *buf, int len) const;
int send(u8 *buf, int len);
// TODO: de-virtualise this when existing devices implement delayed receive
virtual void recv_cb(u8 *buf, int len);
@ -40,6 +42,7 @@ protected:
float m_bandwidth;
std::unique_ptr<osd_netdev> m_dev;
int m_intf;
bool m_loopback_control;
emu_timer *m_send_timer;
emu_timer *m_recv_timer;

View File

@ -509,7 +509,7 @@ uint8_t sun2_state::ethernet_r()
void sun2_state::ethernet_w(uint8_t data)
{
m_edlc->reset_w(!BIT(data, 7));
// Bit 6 = loopback control (active low, though inverted for MB502)
m_edlc->set_loopback(!BIT(data, 6)); // LBC on MB502
m_edlc->ca(BIT(data, 5));
m_ethernet_status = (data & 0xf0) | (m_ethernet_status & 0x0f);
@ -570,6 +570,7 @@ void sun2_state::vmetype1space_map(address_map &map)
// 7f1000-7f17ff: AM9518 encryption processor
//AM_RANGE(0x7f1800, 0x7f1801) AM_DEVREADWRITE8(SCC1_TAG, z80scc_device, cb_r, cb_w, 0xff00)
//AM_RANGE(0x7f1802, 0x7f1803) AM_DEVREADWRITE8(SCC1_TAG, z80scc_device, db_r, db_w, 0xff00)
map(0x7f1804, 0x7f1805).nopr();
//AM_RANGE(0x7f1804, 0x7f1805) AM_DEVREADWRITE8(SCC1_TAG, z80scc_device, ca_r, ca_w, 0xff00)
//AM_RANGE(0x7f1806, 0x7f1807) AM_DEVREADWRITE8(SCC1_TAG, z80scc_device, da_r, da_w, 0xff00)
map(0x7f2000, 0x7f2000).rw(SCC2_TAG, FUNC(z80scc_device::cb_r), FUNC(z80scc_device::cb_w));