mame/src/osd/osdnet.cpp
Patrick Mackinlay 8919ce5645 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
2018-09-04 19:26:58 +10:00

140 lines
2.9 KiB
C++

// license:BSD-3-Clause
// copyright-holders:Carl
#include "emu.h"
#include "osdnet.h"
static class std::vector<std::unique_ptr<osd_netdev::entry_t>> netdev_list;
void add_netdev(const char *name, const char *description, create_netdev func)
{
auto entry = make_unique_clear<osd_netdev::entry_t>();
entry->id = netdev_list.size();
strncpy(entry->name, name, 255);
entry->name[255] = '\0';
strncpy(entry->description, (description != nullptr) ? description : "(no name)", 255);
entry->description[255] = '\0';
entry->func = func;
netdev_list.push_back(std::move(entry));
}
void clear_netdev()
{
netdev_list.clear();
}
const std::vector<std::unique_ptr<osd_netdev::entry_t>>& get_netdev_list()
{
return netdev_list;
}
class osd_netdev *open_netdev(int id, class device_network_interface *ifdev, int rate)
{
for(auto &entry : netdev_list)
if(entry->id==id)
return entry->func(entry->name, ifdev, rate);
return nullptr;
}
osd_netdev::osd_netdev(class device_network_interface *ifdev, int rate)
{
m_dev = ifdev;
m_timer = ifdev->device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(osd_netdev::recv), this));
m_timer->adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate));
}
osd_netdev::~osd_netdev()
{
}
void osd_netdev::start()
{
m_timer->enable(true);
}
void osd_netdev::stop()
{
m_timer->enable(false);
}
int osd_netdev::send(uint8_t *buf, int len)
{
return 0;
}
void osd_netdev::recv(void *ptr, int param)
{
uint8_t *buf;
int len;
//const char atalkmac[] = { 0x09, 0x00, 0x07, 0xff, 0xff, 0xff };
while(m_timer->enabled() && (len = recv_dev(&buf)))
{
#if 0
if(buf[0] & 1)
{
if(memcmp("\xff\xff\xff\xff\xff\xff", buf, 6) && memcmp(atalkmac, buf, 6) && !m_dev->mcast_chk(buf, len)) continue;
}
else {
//const unsigned char *ourmac = (const unsigned char *)get_mac();
//printf("our mac: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X dst mac: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", ourmac[0], ourmac[1], ourmac[2], ourmac[3], ourmac[4], ourmac[5], buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
if(memcmp(get_mac(), buf, 6) && !get_promisc()) continue;
}
#endif
m_dev->recv_cb(buf, len);
}
}
int osd_netdev::recv_dev(uint8_t **buf)
{
return 0;
}
void osd_netdev::set_mac(const char *mac)
{
}
void osd_netdev::set_promisc(bool promisc)
{
}
bool osd_netdev::get_promisc()
{
if(m_dev)
return m_dev->get_promisc();
return false;
}
const char *osd_netdev::get_mac()
{
if(m_dev)
return m_dev->get_mac();
return "\0\0\0\0\0\0";
}
int netdev_count()
{
return netdev_list.size();
}
void osd_list_network_adapters(void)
{
#ifdef USE_NETWORK
int num_devs = netdev_list.size();
if (num_devs == 0)
{
printf("No network adapters were found\n");
return;
}
printf("Available network adapters:\n");
for (auto &entry : netdev_list)
{
printf(" %s\n", entry->description);
}
#else
printf("Network is not supported in this build\n");
#endif
}