summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/dinetwork.cpp
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2018-09-04 16:26:58 +0700
committer Vas Crabb <cuavas@users.noreply.github.com>2018-09-04 19:26:58 +1000
commit8919ce5645fd0fba7e470ac72fa76553934aea6a (patch)
tree554c0eb6cf3efb48d1e151bb400e53776d05ca77 /src/emu/dinetwork.cpp
parent21fa0dfd4f77be20bd6a86848e40be641b687af5 (diff)
interpro: notworking -> networking (#3815)
* interpro: notworking -> networking These changes combine to make InterPro networking work on Windows with the TAP-Windows6 driver. * osdnet: add a receive delay (1 frame) after transmit to avoid a time-travel problem * taptun: pad short Ethernet frames and append FCS (Windows-only until Linux taptun behaviour is verified) * clipper: fix bugs in carry flag handling, prefer sign bit for tests * i82586: fix transmit bug, handle reset * networking: delayed transmit/receive A second attempt to fix networking on InterPro systems, by introducing somewhat realistic delays into network transmit and receive paths. This version works by adding functions to device_network_interface which enable a device to be informed when the transmit or receive completes. The delay is only crudely approximated based on the specified bandwidth and the number of bytes being transmitted, but it should be good enough in practice. Existing drivers should not be impacted by these changes; overriding the new functions (and no longer overriding recv_cb) is necessary to obtain the new behaviour. Changes from the previous commit: * i82586: improve interrupt handling, implement delayed transmit/receive behaviour * dinetwork: add transmit/receive delay timers, handlers and logic * osdnet: remove receive delay, add the ability to start the receive timer
Diffstat (limited to 'src/emu/dinetwork.cpp')
-rw-r--r--src/emu/dinetwork.cpp44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/emu/dinetwork.cpp b/src/emu/dinetwork.cpp
index ee8374a4397..412e37fb060 100644
--- a/src/emu/dinetwork.cpp
+++ b/src/emu/dinetwork.cpp
@@ -16,14 +16,56 @@ device_network_interface::~device_network_interface()
{
}
+void device_network_interface::interface_pre_start()
+{
+ m_send_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_network_interface::send_complete), this));
+ 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
{
if(!m_dev) return 0;
- return m_dev->send(buf, 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");
+
+ // send the data
+ int result = m_dev->send(buf, len);
+
+ // schedule transmit complete callback
+ m_send_timer->adjust(attotime::from_ticks(len, m_bandwidth * 1'000'000 / 8), result);
+
+ return result;
+}
+
+TIMER_CALLBACK_MEMBER(device_network_interface::send_complete)
+{
+ send_complete_cb(param);
}
void device_network_interface::recv_cb(u8 *buf, int len)
{
+ assert_always(!m_recv_timer->enabled(), "attempted to receive while receive already in progress");
+
+ // process the received data
+ int result = recv_start_cb(buf, len);
+
+ if (result)
+ {
+ // stop receiving more data from the network
+ m_dev->stop();
+
+ // schedule receive complete callback
+ m_recv_timer->adjust(attotime::from_ticks(len, m_bandwidth * 1'000'000 / 8), result);
+ }
+}
+
+TIMER_CALLBACK_MEMBER(device_network_interface::recv_complete)
+{
+ recv_complete_cb(param);
+
+ // start receiving data from the network again
+ m_dev->start();
}
void device_network_interface::set_promisc(bool promisc)