summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-05-26 22:14:18 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-05-26 22:16:24 -0400
commit2090f71585677a74ae7cf27606ad401dbcda9e23 (patch)
treef4827c5b83541eb493c65be626904baa9e036f91
parentb956b4112506094d43e558ed061075b0f2cb8591 (diff)
dinetwork: Add loopback control (nw)
-rw-r--r--src/emu/dinetwork.cpp44
-rw-r--r--src/emu/dinetwork.h5
-rw-r--r--src/mame/drivers/sun2.cpp3
3 files changed, 46 insertions, 6 deletions
diff --git a/src/emu/dinetwork.cpp b/src/emu/dinetwork.cpp
index 094d3476af1..cc1c4402759 100644
--- a/src/emu/dinetwork.cpp
+++ b/src/emu/dinetwork.cpp
@@ -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();
+ }
+}
diff --git a/src/emu/dinetwork.h b/src/emu/dinetwork.h
index fa5ee730a87..d844be951ab 100644
--- a/src/emu/dinetwork.h
+++ b/src/emu/dinetwork.h
@@ -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;
diff --git a/src/mame/drivers/sun2.cpp b/src/mame/drivers/sun2.cpp
index c7efe8fa685..e63f5d6560f 100644
--- a/src/mame/drivers/sun2.cpp
+++ b/src/mame/drivers/sun2.cpp
@@ -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));