#include "crc32.h"
#include "savestate.h"
#include "autoconf.h"
+#include "rommgr.h"
#define DUMPPACKET 0
static int dofakemac (uae_u8 *packet)
{
+ if (!memcmp(fakemac, realmac, 6)) {
+ return 1;
+ }
if (!memcmp (packet, fakemac, 6)) {
memcpy (packet, realmac, 6);
return 1;
if (len < 20)
return 0;
+ if (!memcmp(fakemac, realmac, 6))
+ return len;
#if DUMPPACKET
dumppacket (_T("pre:"), packet, len);
#endif
if (csr[0] & (CSR0_BABL | CSR0_MISS | CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IDON))
csr[0] |= CSR0_INTR;
if ((csr[0] & (CSR0_INTR | CSR0_INEA)) == (CSR0_INTR | CSR0_INEA)) {
+ set_special_exter(SPCFLAG_UAEINT);
atomic_or(&uae_int_requested, 4);
if (!was && log_a2065 > 2)
write_log(_T("A2065 +IRQ\n"));
ew (0x10, 0x02);
ew (0x14, 0x02);
+ // 0x00 0x80 0x10 = Commodore MAC range, A2065 drivers expect it.
+
td = NULL;
- if (ethernet_enumerate (&td, currprefs.a2065name)) {
- memcpy (realmac, td->mac, sizeof realmac);
- if (!td->mac[0] && !td->mac[1] && !td->mac[2]) {
- realmac[0] = 0x00;
- realmac[1] = 0x80;
- realmac[2] = 0x10;
+ if (ethernet_enumerate (&td, ROMTYPE_A2065)) {
+ if (!ethernet_getmac(realmac, aci->rc->configtext)) {
+ memcpy (realmac, td->mac, sizeof realmac);
}
+ realmac[0] = 0x00;
+ realmac[1] = 0x80;
+ realmac[2] = 0x10;
if (aci->doinit)
write_log (_T("A2065: '%s' %02X:%02X:%02X:%02X:%02X:%02X\n"),
- td->name, td->mac[0], td->mac[1], td->mac[2], td->mac[3], td->mac[4], td->mac[5]);
+ td->name, realmac[0], realmac[1], realmac[2], realmac[3], realmac[4], realmac[5]);
} else {
realmac[0] = 0x00;
realmac[1] = 0x80;
{
uae_u8 *dstbak,*dst;
- if (currprefs.a2065name[0] == 0)
+ if (!is_board_enabled(&currprefs, ROMTYPE_A2065, 0))
return NULL;
if (dstptr)
dstbak = dst = dstptr;
#ifdef DRIVESOUND
driveclick_reset();
#endif
+ ethernet_reset();
uae_int_requested = 0;
}
rp_pause(pause_emulation);
#endif
pausevideograb(1);
+ ethernet_pause(1);
}
void devices_unpause(void)
uae_ppc_pause(0);
#endif
pausevideograb(0);
+ ethernet_pause(0);
}
#include "sana2.h"
#include "uae/slirp.h"
#include "gui.h"
+#include "rommgr.h"
#ifndef HAVE_INET_ATON
static int inet_aton(const char *cp, struct in_addr *ia)
#endif
}
-bool ethernet_enumerate (struct netdriverdata **nddp, const TCHAR *name)
+bool ethernet_enumerate (struct netdriverdata **nddp, int romtype)
{
int j;
struct netdriverdata *nd;
+ const TCHAR *name = NULL;
+
+ if (romtype) {
+ struct romconfig *rc = get_device_romconfig(&currprefs, romtype, 0);
+ name = ethernet_getselectionname(rc ? rc->device_settings : 0);
+ }
+
gui_flicker_led(LED_NET, 0, 0);
if (name) {
netmode = 0;
}
return 0;
}
+
+bool ethernet_getmac(uae_u8 *m, const TCHAR *mac)
+{
+ if (!mac)
+ return false;
+ if (_tcslen(mac) != 3 * 5 + 2)
+ return false;
+ for (int i = 0; i < 6; i++) {
+ TCHAR *endptr;
+ if (mac[0] == 0 || mac[1] == 0)
+ return false;
+ if (i < 5 && mac[2] != '.')
+ return false;
+ uae_u8 v = (uae_u8)_tcstol(mac, &endptr, 16);
+ mac += 3;
+ m[i] = v;
+ }
+ return true;
+}
#include "x86.h"
#include "filesys.h"
#include "ethernet.h"
+#include "sana2.h"
#define CARD_FLAG_CAN_Z3 1
}
};
-static const struct expansionboardsettings ne2k_isa_settings[] = {
- {
- _T("IO\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"),
- _T("io\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"),
- true, false, 0
- },
- {
- _T("IRQ\0") _T("3\0") _T("4\0") _T("5\0") _T("7\0") _T("9\0") _T("10\0") _T("11\0") _T("12\0") _T("15\0"),
- _T("irq\0") _T("3\0") _T("4\0") _T("5\0") _T("7\0") _T("9\0") _T("10\0") _T("11\0") _T("12\0") _T("15\0"),
- true, false, 0
- },
- {
- NULL
- }
-};
-
-
static const struct expansionboardsettings toccata_soundcard_settings[] = {
{
_T("Paula/CD audio mixer"),
}
};
+static struct expansionboardsettings ne2k_isa_settings[] = {
+ {
+ _T("IO\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"),
+ _T("io\0") _T("240\0") _T("260\0") _T("280\0") _T("2A0\0") _T("300\0") _T("320\0") _T("340\0") _T("360\0"),
+ true, false, 0
+ },
+ {
+ _T("IRQ\0") _T("3\0") _T("4\0") _T("5\0") _T("7\0") _T("9\0") _T("10\0") _T("11\0") _T("12\0") _T("15\0"),
+ _T("irq\0") _T("3\0") _T("4\0") _T("5\0") _T("7\0") _T("9\0") _T("10\0") _T("11\0") _T("12\0") _T("15\0"),
+ true, false, 0
+ },
+ {
+ NULL, NULL,
+ true, false, 4
+ },
+ {
+ NULL
+ }
+};
+
+static struct expansionboardsettings lanrover_settings[] ={
+ {
+ _T("Interrupt level\0") _T("2\0") _T("6\0"),
+ _T("irq\0") _T("2\0") _T("6\0"),
+ true, false, 0
+ },
+ {
+ _T("MAC\0"),
+ _T("mac\0"),
+ 2, false, 0
+ },
+ {
+ NULL, NULL,
+ true, false, 15
+ },
+ {
+ NULL
+ }
+};
+static struct expansionboardsettings ethernet_settings[] = {
+ {
+ _T("MAC\0"),
+ _T("mac\0"),
+ 2, false, 0
+ },
+ {
+ NULL, NULL,
+ true, false, 16
+ },
+ {
+ NULL
+ }
+};
+
+static struct expansionboardsettings *netsettings[] = {
+ ethernet_settings,
+ lanrover_settings,
+ ne2k_isa_settings,
+ NULL
+};
+
+struct netdriverdata **target_ethernet_enumerate(void);
+
+uae_u32 ethernet_getselection(const TCHAR *name)
+{
+ struct netdriverdata **ndd = target_ethernet_enumerate();
+ if (!ndd)
+ return 0;
+ for (int i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) {
+ if (ndd[i] && !_tcsicmp(ndd[i]->name, name))
+ return i << 16;
+ }
+ return 0;
+}
+
+const TCHAR *ethernet_getselectionname(uae_u32 settings)
+{
+ struct netdriverdata **ndd = target_ethernet_enumerate();
+ if (!ndd)
+ return 0;
+ settings = (settings >> 16) & 255;
+ for (int i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) {
+ if (i == settings)
+ return ndd[i]->name;
+ }
+ return _T("slirp");
+}
+
+void ethernet_updateselection(void)
+{
+ static int updated;
+ if (updated)
+ return;
+ updated = 1;
+ struct netdriverdata **ndd = target_ethernet_enumerate();
+ if (!ndd)
+ return;
+ static TCHAR tmp1[MAX_DPATH];
+ static TCHAR tmp2[MAX_DPATH];
+ _tcscpy(tmp1, _T("Network mode"));
+ _tcscpy(tmp2, _T("netmode"));
+ TCHAR *p1 = tmp1 + _tcslen(tmp1) + 1;
+ TCHAR *p2 = tmp2 + _tcslen(tmp2) + 1;
+ for (int i = 0; ndd && i < MAX_TOTAL_NET_DEVICES; i++) {
+ if (ndd[i]) {
+ TCHAR mac[20];
+ mac[0] = 0;
+ if (ndd[i]->type == UAENET_SLIRP || ndd[i]->type == UAENET_SLIRP_INBOUND) {
+ _stprintf(mac, _T(" xx:xx:xx:%02X:%02X:%02X"),
+ ndd[i]->mac[3], ndd[i]->mac[4], ndd[i]->mac[5]);
+ }
+ _stprintf(p1, _T("%s%s"), ndd[i]->desc, mac[0] ? mac : _T(""));
+ p1 += _tcslen(p1) + 1;
+ _tcscpy(p2, ndd[i]->name);
+ p2 += _tcslen(p2) + 1;
+ }
+ }
+ *p1 = 0;
+ *p2 = 0;
+ for (int i = 0; netsettings[i]; i++) {
+ struct expansionboardsettings *ebs = netsettings[i];
+ int j;
+ for (j = 0; ebs[j].name; j++);
+ ebs[j].name = tmp1;
+ ebs[j].configname = tmp2;
+ }
+}
static void fastlane_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
{
_T("a2065"), _T("A2065"), _T("Commodore"),
a2065_init, NULL, NULL, ROMTYPE_A2065 | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
NULL, 0,
- false, EXPANSIONTYPE_NET
+ false, EXPANSIONTYPE_NET,
+ 0, 0, 0, false, NULL,
+ false, 0, ethernet_settings,
},
{
_T("ariadne2"), _T("Ariadne II"), _T("Village Tronic"),
NULL, 0,
false, EXPANSIONTYPE_NET,
0, 0, 0, false, NULL,
- false, 0, NULL,
+ false, 0, ethernet_settings,
{ 0xc1, 0xca, 0x00, 0x00, 2167 >> 8, 2167 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
+ {
+ _T("hydra"), _T("AmigaNet"), _T("Hydra Systems"),
+ hydra_init, NULL, NULL, ROMTYPE_HYDRA | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_NET,
+ 0, 0, 0, false, NULL,
+ false, 0, ethernet_settings,
+ { 0xc1, 0x01, 0x00, 0x00, 2121 >> 8, 2121 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
+ {
+ _T("eb920"), _T("LAN Rover/EB920"), _T("ASDG"),
+ lanrover_init, NULL, NULL, ROMTYPE_LANROVER | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_NET,
+ 0, 0, 0, false, NULL,
+ false, 0, lanrover_settings,
+ { 0xc1, 0xfe, 0x00, 0x00, 1023 >> 8, 1023 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+ },
{
_T("xsurf"), _T("X-Surf"), _T("Individual Computers"),
xsurf_init, NULL, NULL, ROMTYPE_XSURF | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z2, true,
NULL, 0,
false, EXPANSIONTYPE_NET,
0, 0, 0, false, NULL,
- false, 0, NULL,
+ false, 0, ethernet_settings,
{ 0xc1, 0x17, 0x00, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{
NULL, 0,
false, EXPANSIONTYPE_NET,
0, 0, 0, false, NULL,
- false, 0, NULL,
+ false, 0, ethernet_settings,
{ 0xc1, 0x64, 0x10, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00 }
},
{
NULL, 0,
false, EXPANSIONTYPE_NET,
0, 0, 0, false, NULL,
- false, 0, NULL,
+ false, 0, ethernet_settings,
{ 0x82, 0x64, 0x32, 0x00, 4626 >> 8, 4626 & 255, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00 }
},
{
- _T("ne2000_pcmcia"), _T("NE2000 PCMCIA"), NULL,
+ _T("ne2000_pcmcia"), _T("RTL8019 PCMCIA (NE2000 compatible)"), NULL,
gayle_init_ne2000_pcmcia, NULL, NULL, ROMTYPE_NE2KPCMCIA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
NULL, 0,
- false, EXPANSIONTYPE_NET
+ false, EXPANSIONTYPE_NET,
+ 0, 0, 0, false, NULL,
+ false, 0, ethernet_settings,
},
{
- _T("ne2000_pci"), _T("NE2000 PCI"), NULL,
+ _T("ne2000_pci"), _T("RTL8029 PCI (NE2000 compatible)"), NULL,
pci_expansion_init, NULL, NULL, ROMTYPE_NE2KPCI | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
NULL, 0,
- false, EXPANSIONTYPE_NET
+ false, EXPANSIONTYPE_NET,
+ 0, 0, 0, false, NULL,
+ false, 0, ethernet_settings,
},
{
- _T("ne2000_isa"), _T("NE2000 ISA"), NULL,
+ _T("ne2000_isa"), _T("RTL8019 ISA (NE2000 compatible)"), NULL,
isa_expansion_init, NULL, NULL, ROMTYPE_NE2KISA | ROMTYPE_NOT, 0, 0, BOARD_NONAUTOCONFIG_BEFORE, true,
NULL, 0,
false, EXPANSIONTYPE_NET,
#include "pci_hw.h"
#include "debug.h"
#include "autoconf.h"
+#include "rommgr.h"
#define PCMCIA_SRAM 1
#define PCMCIA_IDE 2
ne2000 = &ne2000_pci_board;
ne2000_board_state = xcalloc(pci_board_state, 1);
ne2000_board_state->irq_callback = ne2000_pcmcia_irq_callback;
- if (!ne2000->init(ne2000_board_state)) {
+ if (!ne2000->init(ne2000_board_state, NULL)) {
write_log(_T("NE2000 init failed\n"));
} else {
pcmcia_readonly = true;
#endif
gayle_bank.name = bankname;
gayle_dataflyer_enable(false);
- if (currprefs.ne2000pcmcianame[0])
+ if (is_board_enabled(&currprefs, ROMTYPE_NE2KPCMCIA, 0))
gayle_ne2000_unit(1);
}
void check_prefs_changed_gayle(void)
{
- if (_tcscmp(currprefs.ne2000pcmcianame, changed_prefs.ne2000pcmcianame)) {
- _tcscpy(currprefs.ne2000pcmcianame, changed_prefs.ne2000pcmcianame);
- gayle_ne2000_unit(currprefs.ne2000pcmcianame[0]);
+ if (!currprefs.cs_pcmcia)
+ return;
+ if (is_board_enabled(&currprefs, ROMTYPE_NE2KPCMCIA, 0) != is_board_enabled(&changed_prefs, ROMTYPE_NE2KPCMCIA, 0)) {
+ board_prefs_changed(ROMTYPE_NE2KPCMCIA, 0);
+ gayle_ne2000_unit(is_board_enabled(&currprefs, ROMTYPE_NE2KPCMCIA, 0));
}
}
const TCHAR *desc;
int mtu;
uae_u8 mac[6];
+ uae_u8 originalmac[6];
int active;
};
typedef void (ethernet_gotfunc)(void *dev, const uae_u8 *data, int len);
typedef int (ethernet_getfunc)(void *dev, uae_u8 *d, int *len);
-extern bool ethernet_enumerate (struct netdriverdata **, const TCHAR *name);
+extern bool ethernet_enumerate (struct netdriverdata **, int romtype);
extern void ethernet_enumerate_free (void);
extern void ethernet_close_driver (struct netdriverdata *ndd);
extern void ethernet_trigger (struct netdriverdata *ndd, void*);
extern bool ariadne2_init(struct autoconfig_info *aci);
+extern bool hydra_init(struct autoconfig_info *aci);
+extern bool lanrover_init(struct autoconfig_info *aci);
extern bool xsurf_init(struct autoconfig_info *aci);
extern bool xsurf100_init(struct autoconfig_info *aci);
void ne2000_reset(void);
void ne2000_hsync(void);
+void ethernet_updateselection(void);
+uae_u32 ethernet_getselection(const TCHAR*);
+const TCHAR *ethernet_getselectionname(uae_u32 settings);
+bool ethernet_getmac(uae_u8 *m, const TCHAR *mac);
+
+void ethernet_pause(int);
+void ethernet_reset(void);
+
#endif /* UAE_ETHERNET_H */
#define ROMTYPE_XSURF 0x00100058
#define ROMTYPE_XSURF100Z2 0x00100059
#define ROMTYPE_XSURF100Z3 0x0010005a
+#define ROMTYPE_HYDRA 0x0010005b
+#define ROMTYPE_LANROVER 0x0010005c
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000
struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index);
void clear_device_rom(struct uae_prefs *p, int romtype, int devnum, bool deleteDevice);
struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index);
+bool is_board_enabled(struct uae_prefs *p, int romtype, int devnum);
+void board_prefs_changed(int romtype, int devnum);
#define LOADROM_FILL 1
#define LOADROM_EVENONLY 2
static struct netdriverdata tds[MAX_TOTAL_NET_DEVICES];
static int enumerated;
+static int ethernet_paused;
+
+typedef int(_cdecl *PCAP_FINDALLDEVS_EX)(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
+static PCAP_FINDALLDEVS_EX ppcap_findalldevs_ex;
+typedef void(_cdecl *PCAP_FREEALLDEVS)(pcap_if_t *);
+static PCAP_FREEALLDEVS ppcap_freealldevs;
+typedef pcap_t *(_cdecl *PCAP_OPEN)(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
+static PCAP_OPEN ppcap_open;
+typedef void (_cdecl *PCAP_CLOSE)(pcap_t *);
+static PCAP_CLOSE ppcap_close;
+typedef int (_cdecl *PCAP_DATALINK)(pcap_t *);
+static PCAP_DATALINK ppcap_datalink;
+typedef int (_cdecl *PCAP_SENDPACKET)(pcap_t *, const u_char *, int);
+static PCAP_SENDPACKET ppcap_sendpacket;
+typedef int(_cdecl *PCAP_NEXT_EX)(pcap_t *, struct pcap_pkthdr **, const u_char **);
+static PCAP_NEXT_EX ppcap_next_ex;
+typedef const char *(_cdecl *PCAP_LIB_VERSION)(void);
+static PCAP_LIB_VERSION ppcap_lib_version;
+
+typedef LPADAPTER(_cdecl *PACKETOPENADAPTER)(PCHAR AdapterName);
+static PACKETOPENADAPTER pPacketOpenAdapter;
+typedef VOID(_cdecl *PACKETCLOSEADAPTER)(LPADAPTER lpAdapter);
+static PACKETCLOSEADAPTER pPacketCloseAdapter;
+typedef BOOLEAN (_cdecl *PACKETREQUEST)(LPADAPTER AdapterObject, BOOLEAN Set, PPACKET_OID_DATA OidData);
+static PACKETREQUEST pPacketRequest;
+
+static HMODULE wpcap, packet;
struct uaenetdatawin32
{
uae_sem_post (&sd->sync_semr);
while (sd->threadactiver == 1) {
int r;
- r = pcap_next_ex (sd->fp, &header, &pkt_data);
- if (r == 1) {
+ r = ppcap_next_ex(sd->fp, &header, &pkt_data);
+ if (r == 1 && !ethernet_paused) {
uae_sem_wait (&sd->change_sem);
sd->gotfunc ((struct s2devstruct*)sd->user, pkt_data, header->len);
uae_sem_post (&sd->change_sem);
int towrite = sd->mtu;
uae_sem_wait (&sd->change_sem);
if (sd->getfunc ((struct s2devstruct*)sd->user, sd->writebuffer, &towrite)) {
- pcap_sendpacket (sd->fp, sd->writebuffer, towrite);
+ ppcap_sendpacket(sd->fp, sd->writebuffer, towrite);
donotwait = 1;
}
uae_sem_post (&sd->change_sem);
SetEvent (sd->evttw);
}
+// locally administered unicast MAC: U<<1, A<<1, E<<1
+static const uae_u8 uaemac[] = { 0xaa, 0x82, 0x8a, 0x00, 0x00, 0x00 };
+
int uaenet_open (void *vsd, struct netdriverdata *tc, void *user, uaenet_gotfunc *gotfunc, uaenet_getfunc *getfunc, int promiscuous)
{
struct uaenetdatawin32 *sd = (struct uaenetdatawin32*)vsd;
char *s;
s = ua (tc->name);
- sd->fp = pcap_open (s, 65536, (promiscuous ? PCAP_OPENFLAG_PROMISCUOUS : 0) | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, NULL, sd->errbuf);
+ if (memcmp(tc->mac, tc->originalmac, 6)) {
+ promiscuous = 1;
+ }
+ sd->fp = ppcap_open(s, 65536, (promiscuous ? PCAP_OPENFLAG_PROMISCUOUS : 0) | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 100, NULL, sd->errbuf);
xfree (s);
if (sd->fp == NULL) {
TCHAR *ss = au (sd->errbuf);
xfree (sd->readbuffer);
xfree (sd->writebuffer);
if (sd->fp)
- pcap_close (sd->fp);
+ ppcap_close (sd->fp);
uaeser_initdata (sd, sd->user);
write_log (_T("uaenet_win32 closed\n"));
}
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *alldevs, *d;
int cnt;
- HMODULE hm;
LPADAPTER lpAdapter = 0;
PPACKET_OID_DATA OidData;
struct netdriverdata *tc, *tcp;
pcap_t *fp;
int val;
TCHAR *ss;
+ bool npcap = true;
if (enumerated) {
return enumit (name);
}
tcp = tds;
- hm = LoadLibrary (_T("wpcap.dll"));
- if (hm == NULL) {
- write_log (_T("uaenet: winpcap not installed (wpcap.dll)\n"));
- return NULL;
+ wpcap = LoadLibrary(_T("npcap\\wpcap.dll"));
+ if (wpcap == NULL) {
+ int err = GetLastError();
+ wpcap = LoadLibrary (_T("wpcap.dll"));
+ if (wpcap == NULL) {
+ write_log (_T("uaenet: npcap/winpcap not installed (wpcap.dll)\n"));
+ return NULL;
+ }
+ npcap = false;
}
- FreeLibrary (hm);
- hm = LoadLibrary (_T("packet.dll"));
- if (hm == NULL) {
- write_log (_T("uaenet: winpcap not installed (packet.dll)\n"));
+ packet = LoadLibrary (npcap ? _T("npcap\\packet.dll") : _T("packet.dll"));
+ if (packet == NULL) {
+ write_log (_T("uaenet: npcap/winpcap not installed (packet.dll)\n"));
+ FreeLibrary(wpcap);
+ wpcap = NULL;
return NULL;
}
- FreeLibrary (hm);
- if (!isdllversion (_T("wpcap.dll"), 4, 0, 0, 0)) {
- write_log (_T("uaenet: too old winpcap, v4 or newer required\n"));
+
+ if (!isdllversion (npcap ? _T("npcap\\wpcap.dll") : _T("wpcap.dll"), 4, 0, 0, 0)) {
+ write_log (_T("uaenet: too old npcap/winpcap, v4 or newer required\n"));
return NULL;
}
- ss = au (pcap_lib_version ());
+ ppcap_lib_version = (PCAP_LIB_VERSION)GetProcAddress(wpcap, "pcap_lib_version");
+ ppcap_findalldevs_ex = (PCAP_FINDALLDEVS_EX)GetProcAddress(wpcap, "pcap_findalldevs_ex");
+ ppcap_freealldevs = (PCAP_FREEALLDEVS)GetProcAddress(wpcap, "pcap_freealldevs");
+ ppcap_open = (PCAP_OPEN)GetProcAddress(wpcap, "pcap_open");
+ ppcap_close = (PCAP_CLOSE)GetProcAddress(wpcap, "pcap_close");
+ ppcap_datalink = (PCAP_DATALINK)GetProcAddress(wpcap, "pcap_datalink");
+
+ ppcap_sendpacket = (PCAP_SENDPACKET)GetProcAddress(wpcap, "pcap_sendpacket");
+ ppcap_next_ex = (PCAP_NEXT_EX)GetProcAddress(wpcap, "pcap_next_ex");
+
+ pPacketOpenAdapter = (PACKETOPENADAPTER)GetProcAddress(packet, "PacketOpenAdapter");
+ pPacketCloseAdapter = (PACKETCLOSEADAPTER)GetProcAddress(packet, "PacketCloseAdapter");
+ pPacketRequest = (PACKETREQUEST)GetProcAddress(packet, "PacketRequest");
+
+ ss = au (ppcap_lib_version());
if (!done)
write_log (_T("uaenet: %s\n"), ss);
xfree (ss);
- if (pcap_findalldevs_ex (PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
+ if (ppcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
ss = au (errbuf);
write_log (_T("uaenet: failed to get interfaces: %s\n"), ss);
xfree (ss);
return NULL;
}
+
+ PIP_ADAPTER_ADDRESSES aa = NULL;
+ DWORD aasize = 0;
+ DWORD err = GetAdaptersAddresses(AF_UNSPEC,
+ GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
+ NULL, NULL, &aasize);
+ if (err == ERROR_BUFFER_OVERFLOW) {
+ aa = (IP_ADAPTER_ADDRESSES*)xcalloc(uae_u8, aasize);
+ if (GetAdaptersAddresses(AF_UNSPEC,
+ GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
+ NULL, aa, &aasize) != ERROR_SUCCESS) {
+ xfree(aa);
+ aa = NULL;
+ }
+ }
+
+ OidData = (PPACKET_OID_DATA)xcalloc(uae_u8, 6 + sizeof(PACKET_OID_DATA));
+ OidData->Length = 6;
+ OidData->Oid = OID_802_3_CURRENT_ADDRESS;
+
if (!done)
write_log (_T("uaenet: detecting interfaces\n"));
for(cnt = 0, d = alldevs; d != NULL; d = d->next) {
write_log (_T("- corrupt name\n"));
continue;
}
- fp = pcap_open (d->name, 65536, 0, 0, NULL, errbuf);
+ fp = ppcap_open(d->name, 65536, 0, 0, NULL, errbuf);
if (!fp) {
ss = au (errbuf);
write_log (_T("- pcap_open() failed: %s\n"), ss);
xfree (ss);
continue;
}
- val = pcap_datalink (fp);
- pcap_close (fp);
+ val = ppcap_datalink(fp);
+ ppcap_close (fp);
if (val != DLT_EN10MB) {
if (!done)
write_log (_T("- not an ethernet adapter (%d)\n"), val);
continue;
}
- lpAdapter = PacketOpenAdapter (n2 + strlen (PCAP_SRC_IF_STRING));
+ lpAdapter = pPacketOpenAdapter(n2 + strlen (PCAP_SRC_IF_STRING));
if (lpAdapter == NULL) {
if (!done)
write_log (_T("- PacketOpenAdapter() failed\n"));
continue;
}
- OidData = (PPACKET_OID_DATA)xcalloc (uae_u8, 6 + sizeof(PACKET_OID_DATA));
- if (OidData) {
- OidData->Length = 6;
- OidData->Oid = OID_802_3_CURRENT_ADDRESS;
- if (PacketRequest (lpAdapter, FALSE, OidData)) {
- memcpy (tc->mac, OidData->Data, 6);
- if (!done)
- write_log (_T("- MAC %02X:%02X:%02X:%02X:%02X:%02X (%d)\n"),
- tc->mac[0], tc->mac[1], tc->mac[2],
- tc->mac[3], tc->mac[4], tc->mac[5], cnt);
- tc->type = UAENET_PCAP;
- tc->active = 1;
- tc->mtu = 1522;
- tc->name = au (d->name);
- tc->desc = au (d->description);
- cnt++;
- } else {
- write_log (_T(" - failed to get MAC\n"));
+ memset(tc->originalmac, 0, sizeof tc->originalmac);
+ memcpy(tc->mac, uaemac, 6);
+ if (pPacketRequest (lpAdapter, FALSE, OidData)) {
+ memcpy(tc->mac, OidData->Data, 6);
+ memcpy(tc->originalmac, tc->mac, 6);
+ } else {
+ PIP_ADAPTER_ADDRESSES aap = aa;
+ while (aap) {
+ char *name1 = aap->AdapterName;
+ char *name2 = d->name;
+ while (*name2 && *name2 != '{')
+ name2++;
+ if (*name2 && !stricmp(name1, name2)) {
+ memcpy(tc->mac, aap->PhysicalAddress, 6);
+ memcpy(tc->originalmac, tc->mac, 6);
+ break;
+ }
+ aap = aap->Next;
}
- xfree (OidData);
}
- PacketCloseAdapter (lpAdapter);
+ if (!done)
+ write_log(_T("- MAC %02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X\n"),
+ tc->mac[0], tc->mac[1], tc->mac[2], tc->mac[3], tc->mac[4], tc->mac[5],
+ uaemac[0], uaemac[1], uaemac[2], tc->mac[3], tc->mac[4], tc->mac[5]);
+ memcpy(tc->mac, uaemac, 3);
+ tc->type = UAENET_PCAP;
+ tc->active = 1;
+ tc->mtu = 1522;
+ tc->name = au(d->name);
+ tc->desc = au(d->description);
+ cnt++;
+ pPacketCloseAdapter(lpAdapter);
}
if (!done)
write_log (_T("uaenet: end of detection, %d devices found.\n"), cnt);
done = 1;
- pcap_freealldevs (alldevs);
+ ppcap_freealldevs(alldevs);
+ xfree(OidData);
+ xfree(aa);
enumerated = 1;
return enumit (name);
}
tc[i].active = 0;
}
}
+
+void ethernet_pause(int pause)
+{
+ ethernet_paused = pause;
+}
+
+void ethernet_reset(void)
+{
+ ethernet_paused = 0;
+}
#include "newcpu.h"
#include "custom.h"
#include "debug.h"
+#include "sana2.h"
#include "qemuuaeglue.h"
#include "queue.h"
//#define DEBUG_NE2000
+extern int log_a2065;
+
struct NetClientState
{
struct NE2000State *ne2000state;
s->mem[15] = 0x57;
/* duplicate prom data */
- for(i = 15;i >= 0; i--) {
+ for(i = 15; i >= 0; i--) {
s->mem[2 * i] = s->mem[i];
s->mem[2 * i + 1] = s->mem[i];
}
#define MIN_BUF_SIZE 60
+static bool ne2000_canreceive(NetClientState *nc, const uint8_t *buf)
+{
+ NE2000State *s = qemu_get_nic_opaque(nc);
+ unsigned int mcast_idx;
+ static const uint8_t broadcast_macaddr[6] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ /* XXX: check this */
+ if (s->rxcr & 0x10) {
+ /* promiscuous: receive all */
+ } else {
+ if (!memcmp(buf, broadcast_macaddr, 6)) {
+ /* broadcast address */
+ if (!(s->rxcr & 0x04))
+ return false;
+ } else if (buf[0] & 0x01) {
+ /* multicast */
+ if (!(s->rxcr & 0x08))
+ return false;
+ mcast_idx = compute_mcast_idx(buf);
+ if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
+ return false;
+ } else if (s->dp8390 &&
+ s->c.macaddr.a[0] == buf[0] &&
+ s->c.macaddr.a[1] == buf[1] &&
+ s->c.macaddr.a[2] == buf[2] &&
+ s->c.macaddr.a[3] == buf[3] &&
+ s->c.macaddr.a[4] == buf[4] &&
+ s->c.macaddr.a[5] == buf[5]) {
+ /* match */
+ } else if (!s->dp8390 &&
+ s->mem[0] == buf[0] &&
+ s->mem[2] == buf[1] &&
+ s->mem[4] == buf[2] &&
+ s->mem[6] == buf[3] &&
+ s->mem[8] == buf[4] &&
+ s->mem[10] == buf[5]) {
+ /* match */
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
static ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
{
NE2000State *s = qemu_get_nic_opaque(nc);
int size = size_;
uint8_t *p;
- unsigned int total_len, next, avail, len, index, mcast_idx;
+ unsigned int total_len, next, avail, len, index;
uint8_t buf1[60];
- static const uint8_t broadcast_macaddr[6] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#if defined(DEBUG_NE2000)
write_log("NE2000: received len=%d\n", size);
#endif
- if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
- return -1;
+ if (s->cmd & E8390_STOP)
+ return -1;
- /* XXX: check this */
- if (s->rxcr & 0x10) {
- /* promiscuous: receive all */
- } else {
- if (!memcmp(buf, broadcast_macaddr, 6)) {
- /* broadcast address */
- if (!(s->rxcr & 0x04))
- return size;
- } else if (buf[0] & 0x01) {
- /* multicast */
- if (!(s->rxcr & 0x08))
- return size;
- mcast_idx = compute_mcast_idx(buf);
- if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7))))
- return size;
- } else if (s->mem[0] == buf[0] &&
- s->mem[2] == buf[1] &&
- s->mem[4] == buf[2] &&
- s->mem[6] == buf[3] &&
- s->mem[8] == buf[4] &&
- s->mem[10] == buf[5]) {
- /* match */
- } else {
- return size;
- }
- }
+ if (!ne2000_canreceive(nc, buf))
+ return -1;
+ if (ne2000_buffer_full(s))
+ return -1;
+
+ if (log_a2065 > 1) {
+ const uae_u8 *dstmac = buf;
+ const uae_u8 *srcmac = buf + 6;
+ write_log(_T("NE2000<!DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n"),
+ dstmac[0], dstmac[1], dstmac[2], dstmac[3], dstmac[4], dstmac[5],
+ srcmac[6], srcmac[7], srcmac[8], srcmac[9], srcmac[10], srcmac[11],
+ (buf[12] << 8) | buf[13], size);
+ }
/* if too small buffer, then expand it */
if (size < MIN_BUF_SIZE) {
/* XXX: check this */
if (buf[0] & 0x01)
s->rsr |= ENRSR_PHY;
- p[0] = s->rsr;
- p[1] = next >> 8;
- p[2] = total_len;
- p[3] = total_len >> 8;
+
+ if ((s->dcfg & 2) && s->dp8390) {
+ p[1] = s->rsr;
+ p[0] = next >> 8;
+ p[2] = total_len;
+ p[3] = total_len >> 8;
+ } else {
+ p[0] = s->rsr;
+ p[1] = next >> 8;
+ p[2] = total_len;
+ p[3] = total_len >> 8;
+ }
index += 4;
/* write packet data */
if (addr == E8390_CMD) {
/* control register */
s->cmd = val;
+ if ((val & E8390_STOP) && s->dp8390) {
+ s->isr |= ENISR_RESET;
+ }
if (!(val & E8390_STOP)) { /* START bit makes no sense on RTL8029... */
s->isr &= ~ENISR_RESET;
/* test specific case: zero length transfer */
s->fifo_offset = 0;
xfree(loop);
} else {
+
+ if (log_a2065 > 1) {
+ const uae_u8 *dstmac = transmitbuffer;
+ const uae_u8 *srcmac = transmitbuffer + 6;
+ write_log(_T("NE2000>!DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n"),
+ dstmac[0], dstmac[1], dstmac[2], dstmac[3], dstmac[4], dstmac[5],
+ srcmac[6], srcmac[7], srcmac[8], srcmac[9], srcmac[10], srcmac[11],
+ (transmitbuffer[12] << 8) | transmitbuffer[13], transmitlen);
+ }
+
+
ethernet_trigger(td, sysdata);
}
#if 0
return ret;
}
-static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr,
- uint32_t val)
+static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, uint32_t val)
{
- if (addr < 32 ||
+ if (s->dp8390 || addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
s->mem[addr] = val;
}
}
-static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr,
- uint32_t val)
+static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr, uint32_t val)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (s->dp8390 || addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
*(uint16_t *)(s->mem + addr) = cpu_to_le16(val);
}
}
-static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
- uint32_t val)
+static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr, uint32_t val)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (s->dp8390 || addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
stl_le_p(s->mem + addr, val);
}
static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
{
- if (addr < 32 ||
+ if (s->dp8390 || addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
return s->mem[addr];
} else {
static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (s->dp8390 || addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
return le16_to_cpu(*(uint16_t *)(s->mem + addr));
} else {
static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
{
addr &= ~1; /* XXX: check exact behaviour if not even */
- if (addr < 32 ||
+ if (s->dp8390 || addr < 32 ||
(addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
return ldl_le_p(s->mem + addr);
} else {
#ifdef DEBUG_NE2000
write_log("NE2000: %d byte received (%d %d)\n", len, receive_buffer_read, receive_buffer_write);
#endif
+ // immediately check if we don't need this packet. for better performance.
+ if (!ne2000_canreceive(&ncs, databuf))
+ return;
ne2000_receive_check();
if (len > MAX_PACKET_SIZE)
return;
sysdata = NULL;
xfree(receive_buffer);
receive_buffer = NULL;
- if (ncs.ne2000state)
+ if (ncs.ne2000state) {
eeprom93xx_free(ncs.ne2000state->eeprom);
+ ncs.ne2000state->eeprom = NULL;
+ }
uae_sem_destroy(&ne2000_sem);
}
NE2000State *s = (NE2000State*)opaque;
s->byteswapsupported = true;
}
+static void ne2000_setisdp8390(void *opaque)
+{
+ NE2000State *s = (NE2000State*)opaque;
+ s->dp8390 = true;
+}
+
-static uae_u8 e9346[128] = {
+static uae_u8 e9346[64 * 2] = {
0x80, 0x00, 0x10, 0x00 // CONFIG1-4
};
-static bool ne2000_init(struct pci_board_state *pcibs)
+static bool ne2000_init_2(struct pci_board_state *pcibs, int romtype, const TCHAR *mac)
{
ne2000_free(pcibs);
ncs.device = &ne2000_pci_board;
td = NULL;
uae_u8 *m = ncs.ne2000state->c.macaddr.a;
- const TCHAR *name = currprefs.ne2000pciname[0] ? currprefs.ne2000pciname : currprefs.ne2000pcmcianame; // hack!
- memset(m, 0, 6);
-
- if (name[0] == 0)
- name = _T("slirp");
- if (ethernet_enumerate(&td, name)) {
- memcpy(m, td->mac, 6);
- if (!m[0] && !m[1] && !m[2]) {
- m[0] = 0x52;
- m[1] = 0x54;
- m[2] = 0x05;
+ memset(m, 0, 6);
+ if (ethernet_enumerate(&td, romtype)) {
+ if (!ethernet_getmac(m, mac)) {
+ memcpy(m, td->mac, 6);
+ if (!m[0] && !m[1] && !m[2]) {
+ m[0] = 0x52;
+ m[1] = 0x54;
+ m[2] = 0x05;
+ }
}
write_log(_T("NE2000: '%s' %02X:%02X:%02X:%02X:%02X:%02X\n"),
- td->name, td->mac[0], td->mac[1], td->mac[2], td->mac[3], td->mac[4], td->mac[5]);
+ td->name, m[0], m[1], m[2], m[3], m[4], m[5]);
} else {
m[0] = 0x52;
m[1] = 0x54;
return true;
}
+static bool ne2000_init(struct pci_board_state *pcibs, struct autoconfig_info *aci)
+{
+ return ne2000_init_2(pcibs, ROMTYPE_NE2KPCI, aci->rc->configtext);
+}
static const struct pci_config ne2000_pci_config =
{
0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1, 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39
};
-static const uae_u8 rtl8029as_pnpdata[] =
+static const uae_u8 rtl8019as_pnpdata[] =
{
0x4a, 0x8c, 0x80, 0x19,
0x0d, 0x00, 0x19, 0x00,
int ne2000_romtype;
uae_u32 flags;
struct isapnp pnp;
+ bool level6;
};
static struct ne2000_s ne2000_data;
addr >>= 1;
addr &= 0x1f;
return addr;
+ } else if (ne->ne2000_romtype == ROMTYPE_LANROVER) {
+ if ((addr & 0xc000) == 0x8000) {
+ int maddr = addr & 16383;
+ // memory
+ if (size == -4) {
+ uae_u16 vv = v >> 16;
+ vv = (vv >> 8) | (vv << 8);
+ ne2000_mem_writew(ncs.ne2000state, maddr + 0, vv);
+ vv = v;
+ vv = (vv >> 8) | (vv << 8);
+ ne2000_mem_writew(ncs.ne2000state, maddr + 2, vv);
+ } else if (size == -2) {
+ v = (v >> 8) | (v << 8);
+ ne2000_mem_writew(ncs.ne2000state, maddr, v);
+ } else if (size == -1) {
+ ne2000_mem_writeb(ncs.ne2000state, maddr, v);
+ } else if (size == 4) {
+ *bs = true;
+ *vp = ne2000_mem_readw(ncs.ne2000state, maddr) << 16;
+ *vp |= ne2000_mem_readw(ncs.ne2000state, maddr + 2) << 0;
+ } else if (size == 2) {
+ *bs = true;
+ *vp = ne2000_mem_readw(ncs.ne2000state, maddr);
+ } else if (size == 1) {
+ *vp = ne2000_mem_readb(ncs.ne2000state, maddr);
+ }
+ } else if ((addr & 0x8101) == 0x0100) {
+ // mac rom
+ *vp = ncs.ne2000state->c.macaddr.a[(addr >> 1) & 7];
+ } else if ((addr & 0x8101) == 0x0001) {
+ // io
+ addr &= (15 << 1);
+ addr >>= 1;
+ return addr;
+ }
+ } else if (ne->ne2000_romtype == ROMTYPE_HYDRA) {
+ if (!(addr & 0xc000)) {
+ int maddr = addr;
+ // memory
+ if (size == -4) {
+ uae_u16 vv = v >> 16;
+ vv = (vv >> 8) | (vv << 8);
+ ne2000_mem_writew(ncs.ne2000state, maddr + 0, vv);
+ vv = v;
+ vv = (vv >> 8) | (vv << 8);
+ ne2000_mem_writew(ncs.ne2000state, maddr + 2, vv);
+ } else if (size == -2) {
+ v = (v >> 8) | (v << 8);
+ ne2000_mem_writew(ncs.ne2000state, maddr, v);
+ } else if (size == -1) {
+ ne2000_mem_writeb(ncs.ne2000state, maddr, v);
+ } else if (size == 4) {
+ *bs = true;
+ *vp = ne2000_mem_readw(ncs.ne2000state, maddr) << 16;
+ *vp |= ne2000_mem_readw(ncs.ne2000state, maddr + 2) << 0;
+ } else if (size == 2) {
+ *bs = true;
+ *vp = ne2000_mem_readw(ncs.ne2000state, maddr);
+ } else if (size == 1) {
+ *vp = ne2000_mem_readb(ncs.ne2000state, maddr);
+ }
+ } else if ((addr & 0xffe1) == 0xffc0) {
+ // mac rom
+ *vp = ncs.ne2000state->c.macaddr.a[(addr >> 1) & 7];
+ } else if ((addr & 0xffe1) == 0xffe1) {
+ // io
+ addr &= (15 << 1);
+ addr >>= 1;
+ return addr;
+ }
} else if (ne->ne2000_romtype == ROMTYPE_XSURF) {
if (addr == 0x7e && size == -1) {
ne->flags &= ~1;
w = (w >> 8) | (w << 8);
}
v |= w;
+ } else {
+ if (bs) {
+ uae_u32 l = v;
+ uae_u16 w = l >> 16;
+ w = (w >> 8) | (w << 8);
+ v = w << 16;
+ w = l;
+ w = (w >> 8) | (w << 8);
+ v |= w;
+ }
}
#if ARIADNE2_LOG
write_log(_T("NE2000 LGET %08x %08X %d %08X\n"), addr, v, reg, M68K_GETPC);
struct ne2000_s *ne = getne2k(0);
if (!ne->ariadne2_board_state)
return;
- if (ne->ariadne2_irq)
- INTREQ_0(0x8000 | 0x0008);
+ if (ne->ariadne2_irq) {
+ if (ne->level6)
+ INTREQ_0(0x8000 | 0x2000);
+ else
+ INTREQ_0(0x8000 | 0x0008);
+ }
}
void ne2000_hsync(void)
ne->ariadne2_board_state = xcalloc(pci_board_state, 1);
ne->ariadne2_board_state->irq_callback = ariadne2_irq_callback;
- if (!ne2000_pci_board.init(ne->ariadne2_board_state))
+ if (!ne2000_init_2(ne->ariadne2_board_state, ne->ne2000_romtype, aci->rc->configtext))
return false;
ne2000_byteswapsupported(&ne2000state);
return true;
}
+bool hydra_init(struct autoconfig_info *aci)
+{
+ struct ne2000_s *ne = getne2k(0);
+ ne->ariadne2_irq = false;
+ if (aci->postinit) {
+ return true;
+ }
+ ne->ne2000_romtype = ROMTYPE_HYDRA;
+ const struct expansionromtype *ert = get_device_expansion_rom(ne->ne2000_romtype);
+ aci->autoconfigp = ert->autoconfig;
+ aci->addrbank = &ariadne2_bank;
+ aci->autoconfig_automatic = true;
+ if (!aci->doinit)
+ return true;
+
+ ne->ariadne2_board_state = xcalloc(pci_board_state, 1);
+ ne->ariadne2_board_state->irq_callback = ariadne2_irq_callback;
+ if (!ne2000_init_2(ne->ariadne2_board_state, ne->ne2000_romtype, aci->rc->configtext))
+ return false;
+ ne2000_setisdp8390(&ne2000state);
+
+ return true;
+}
+
+bool lanrover_init(struct autoconfig_info *aci)
+{
+ struct ne2000_s *ne = getne2k(0);
+ ne->ariadne2_irq = false;
+ if (aci->postinit) {
+ return true;
+ }
+ ne->ne2000_romtype = ROMTYPE_LANROVER;
+ const struct expansionromtype *ert = get_device_expansion_rom(ne->ne2000_romtype);
+ aci->autoconfigp = ert->autoconfig;
+ aci->addrbank = &ariadne2_bank;
+ aci->autoconfig_automatic = true;
+ if (!aci->doinit)
+ return true;
+
+ ne->ariadne2_board_state = xcalloc(pci_board_state, 1);
+ ne->ariadne2_board_state->irq_callback = ariadne2_irq_callback;
+ if (!ne2000_init_2(ne->ariadne2_board_state, ne->ne2000_romtype, aci->rc->configtext))
+ return false;
+ ne2000_setisdp8390(&ne2000state);
+ ne->level6 = (aci->rc->device_settings & 1) != 0;
+
+ return true;
+}
+
bool xsurf_init(struct autoconfig_info *aci)
{
struct ne2000_s *ne = getne2k(0);
ne->ariadne2_board_state = xcalloc(pci_board_state, 1);
ne->ariadne2_board_state->irq_callback = ariadne2_irq_callback;
- if (!ne2000_pci_board.init(ne->ariadne2_board_state))
+ if (!ne2000_init_2(ne->ariadne2_board_state, ne->ne2000_romtype, aci->rc->configtext))
return false;
- isapnp_init(&ne->pnp, rtl8029as_pnpdata, sizeof rtl8029as_pnpdata, rt_pnp_init_key, 32);
+ isapnp_init(&ne->pnp, rtl8019as_pnpdata, sizeof rtl8019as_pnpdata, rt_pnp_init_key, 32);
ne2000_byteswapsupported(&ne2000state);
ne2000_setident(&ne2000state, 0x50, 0x70);
ne->ariadne2_board_state = xcalloc(pci_board_state, 1);
ne->ariadne2_board_state->irq_callback = ariadne2_irq_callback;
- if (!ne2000_pci_board.init(ne->ariadne2_board_state))
+ if (!ne2000_init_2(ne->ariadne2_board_state, ne->ne2000_romtype, aci->rc->configtext))
return false;
ne2000_setident(&ne2000state, 0x50, 0x70);
void *eeprom;
bool byteswapsupported;
uae_u8 idbytes[2];
+ bool dp8390;
} NE2000State;
#if 0