diff --git a/AppleWin/Applewin.vcproj b/AppleWin/Applewin.vcproj
index c0de75da..7685a782 100644
--- a/AppleWin/Applewin.vcproj
+++ b/AppleWin/Applewin.vcproj
@@ -308,6 +308,52 @@
RelativePath=".\source\Debugger_Types.h">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
*/
#include "StdAfx.h"
#pragma hdrstop
#include "..\resource\resource.h"
+#include "Tfe\Tfesupp.h"
+#include "Tfe\Uilib.h"
TCHAR computerchoices[] = TEXT("Apple ][+\0")
@@ -300,9 +304,13 @@ static BOOL CALLBACK ConfigDlgProc (HWND window,
case IDC_BENCHMARK:
afterclose = WM_USER_BENCHMARK;
- PropSheet_PressButton(GetParent(window), PSBTN_OK);
+ PropSheet_PressButton(GetParent(window), PSBTN_OK);
break;
+ case IDC_ETHERNET:
+ ui_tfe_settings_dialog(window);
+ break;
+
case IDC_MONOCOLOR:
VideoChooseColor();
break;
@@ -942,6 +950,244 @@ static BOOL CALLBACK DiskDlgProc (HWND window,
return 0;
}
+static BOOL get_tfename(int number, char **ppname, char **ppdescription)
+{
+ if (tfe_enumadapter_open()) {
+ char *pname = NULL;
+ char *pdescription = NULL;
+
+ while (number--) {
+ if (!tfe_enumadapter(&pname, &pdescription))
+ break;
+
+ lib_free(pname);
+ lib_free(pdescription);
+ }
+
+ if (tfe_enumadapter(&pname, &pdescription)) {
+ *ppname = pname;
+ *ppdescription = pdescription;
+ tfe_enumadapter_close();
+ return TRUE;
+ }
+
+ tfe_enumadapter_close();
+ }
+ return FALSE;
+}
+
+static int gray_ungray_items(HWND hwnd)
+{
+ int enable;
+ int number;
+
+ int disabled = 0;
+
+ //resources_get_value("ETHERNET_DISABLED", (void *)&disabled);
+ LOAD(TEXT("Uthernet Disabled") ,(DWORD *)&disabled);
+ get_disabled_state(&disabled);
+
+ if (disabled) {
+ EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE_T), 0);
+ EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE), 0);
+ EnableWindow(GetDlgItem(hwnd, IDOK), 0);
+ SetWindowText(GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE_NAME), "");
+ SetWindowText(GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE_DESC), "");
+ enable = 0;
+ } else {
+ enable = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE),
+ CB_GETCURSEL, 0, 0) ? 1 : 0;
+ }
+
+ EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_T), enable);
+ EnableWindow(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE), enable);
+
+ if (enable) {
+ char *pname = NULL;
+ char *pdescription = NULL;
+
+ number = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE),
+ CB_GETCURSEL, 0, 0);
+
+ if (get_tfename(number, &pname, &pdescription)) {
+ SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME),
+ pname);
+ SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC),
+ pdescription);
+ lib_free(pname);
+ lib_free(pdescription);
+ }
+ } else {
+ SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME), "");
+ SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC), "");
+ }
+
+ return disabled ? 1 : 0;
+}
+
+static uilib_localize_dialog_param tfe_dialog[] = {
+ {0, IDS_TFE_CAPTION, -1},
+ {IDC_TFE_SETTINGS_ENABLE_T, IDS_TFE_ETHERNET, 0},
+ {IDC_TFE_SETTINGS_INTERFACE_T, IDS_TFE_INTERFACE, 0},
+ {IDOK, IDS_OK, 0},
+ {IDCANCEL, IDS_CANCEL, 0},
+ {0, 0, 0}
+};
+
+static uilib_dialog_group tfe_leftgroup[] = {
+ {IDC_TFE_SETTINGS_ENABLE_T, 0},
+ {IDC_TFE_SETTINGS_INTERFACE_T, 0},
+ {0, 0}
+};
+
+static uilib_dialog_group tfe_rightgroup[] = {
+ {IDC_TFE_SETTINGS_ENABLE, 0},
+ {IDC_TFE_SETTINGS_INTERFACE, 0},
+ {0, 0}
+};
+
+static void init_tfe_dialog(HWND hwnd)
+{
+ HWND temp_hwnd;
+ int active_value;
+
+ int tfe_enable;
+ int xsize, ysize;
+
+ char *interface_name = NULL;
+
+ uilib_get_group_extent(hwnd, tfe_leftgroup, &xsize, &ysize);
+ uilib_adjust_group_width(hwnd, tfe_leftgroup);
+ uilib_move_group(hwnd, tfe_rightgroup, xsize + 30);
+
+// resources_get_value("ETHERNET_ACTIVE", (void *)&tfe_enabled);
+ get_tfe_enabled(&tfe_enable);
+
+ //resources_get_value("ETHERNET_AS_RR", (void *)&tfe_as_rr_net);
+ active_value = (tfe_enable ? 1 : 0);
+
+ temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_ENABLE);
+ SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Disabled");
+ SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)"Uthernet");
+ SendMessage(temp_hwnd, CB_SETCURSEL, (WPARAM)active_value, 0);
+
+// resources_get_value("ETHERNET_INTERFACE", (void *)&interface_name);
+ interface_name = (char *) get_tfe_interface();
+
+ if (tfe_enumadapter_open()) {
+ int cnt = 0;
+
+ char *pname;
+ char *pdescription;
+
+ temp_hwnd=GetDlgItem(hwnd,IDC_TFE_SETTINGS_INTERFACE);
+
+ for (cnt = 0; tfe_enumadapter(&pname, &pdescription); cnt++) {
+ BOOL this_entry = FALSE;
+
+ if (strcmp(pname, interface_name) == 0) {
+ this_entry = TRUE;
+ }
+
+ SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_NAME),
+ pname);
+ SetWindowText(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE_DESC),
+ pdescription);
+ SendMessage(temp_hwnd, CB_ADDSTRING, 0, (LPARAM)pname);
+ lib_free(pname);
+ lib_free(pdescription);
+
+ if (this_entry) {
+ SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_INTERFACE),
+ CB_SETCURSEL, (WPARAM)cnt, 0);
+ }
+ }
+
+ tfe_enumadapter_close();
+ }
+
+ if (gray_ungray_items(hwnd)) {
+ /* we have a problem: TFE is disabled. Give a message to the user */
+ MessageBox( hwnd,
+ "TFE support is not available on your system,\n"
+ "there is some important part missing. Please have a\n"
+ "look at the VICE knowledge base support page\n"
+ "\n http://www.vicekb.de.vu/13-005.htm\n\n"
+ "for possible reasons and to activate networking with VICE.",
+ "TFE support", MB_ICONINFORMATION|MB_OK);
+
+ /* just quit the dialog before it is open */
+ SendMessage( hwnd, WM_COMMAND, IDCANCEL, 0);
+ }
+}
+
+
+static void save_tfe_dialog(HWND hwnd)
+{
+ int active_value;
+ int tfe_enabled;
+ char buffer[256];
+
+ buffer[255] = 0;
+ GetDlgItemText(hwnd, IDC_TFE_SETTINGS_INTERFACE, buffer, 255);
+
+ // RGJ - Added check for NULL interface so we don't set it active without a valid interface selected
+ if (strlen(buffer) > 0) {
+ RegSaveString(TEXT("Configuration"), TEXT("Uthernet Interface"), 1, buffer);
+
+ active_value = SendMessage(GetDlgItem(hwnd, IDC_TFE_SETTINGS_ENABLE),
+ CB_GETCURSEL, 0, 0);
+
+ tfe_enabled = active_value >= 1 ? 1 : 0;
+ SAVE(TEXT("Uthernet Active") ,tfe_enabled);
+ } else {
+ SAVE(TEXT("Uthernet Active") ,0);
+ }
+
+
+}
+
+static BOOL CALLBACK TfeDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ switch (msg) {
+ case WM_COMMAND:
+ switch (LOWORD(wparam)) {
+ case IDOK:
+ save_tfe_dialog(hwnd);
+ /* FALL THROUGH */
+
+ case IDCANCEL:
+ EndDialog(hwnd,0);
+ return TRUE;
+
+ case IDC_TFE_SETTINGS_INTERFACE:
+ /* FALL THROUGH */
+
+ case IDC_TFE_SETTINGS_ENABLE:
+ gray_ungray_items(hwnd);
+ break;
+ }
+ return FALSE;
+
+ case WM_CLOSE:
+ EndDialog(hwnd,0);
+ return TRUE;
+
+ case WM_INITDIALOG:
+ init_tfe_dialog(hwnd);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void ui_tfe_settings_dialog(HWND hwnd)
+{
+ DialogBox(instance, (LPCTSTR)IDD_TFE_SETTINGS_DIALOG, hwnd,
+ TfeDlgProc);
+}
+
+
//===========================================================================
void PSP_Init()
diff --git a/AppleWin/source/PropertySheetPage.h b/AppleWin/source/PropertySheetPage.h
index 42d4d78d..a7abfd71 100644
--- a/AppleWin/source/PropertySheetPage.h
+++ b/AppleWin/source/PropertySheetPage.h
@@ -3,3 +3,6 @@
void PSP_Init();
DWORD PSP_GetVolumeMax();
bool PSP_SaveStateSelectImage(HWND hWindow, bool bSave);
+void ui_tfe_settings_dialog(HWND hwnd);
+void * get_tfe_interface(void);
+void get_tfe_enabled(int *tfe_enabled);
diff --git a/AppleWin/source/StdAfx.h b/AppleWin/source/StdAfx.h
index 3528228e..7e946e3d 100644
--- a/AppleWin/source/StdAfx.h
+++ b/AppleWin/source/StdAfx.h
@@ -38,4 +38,5 @@
#include "SerialComms.h"
#include "SoundCore.h"
#include "Speaker.h"
+#include "Tfe/Tfe.h"
#include "Video.h"
diff --git a/AppleWin/source/Tfe/Bittypes.h b/AppleWin/source/Tfe/Bittypes.h
new file mode 100644
index 00000000..654f37b1
--- /dev/null
+++ b/AppleWin/source/Tfe/Bittypes.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _BITTYPES_H
+#define _BITTYPES_H
+
+#ifndef HAVE_U_INT8_T
+
+#if SIZEOF_CHAR == 1
+typedef unsigned char u_int8_t;
+typedef signed char int8_t;
+#elif SIZEOF_INT == 1
+typedef unsigned int u_int8_t;
+typedef signed int int8_t;
+#else /* XXX */
+#error "there's no appropriate type for u_int8_t"
+#endif
+#define HAVE_U_INT8_T 1
+#define HAVE_INT8_T 1
+
+#endif /* HAVE_U_INT8_T */
+
+#ifndef HAVE_U_INT16_T
+
+#if SIZEOF_SHORT == 2
+typedef unsigned short u_int16_t;
+typedef signed short int16_t;
+#elif SIZEOF_INT == 2
+typedef unsigned int u_int16_t;
+typedef signed int int16_t;
+#elif SIZEOF_CHAR == 2
+typedef unsigned char u_int16_t;
+typedef signed char int16_t;
+#else /* XXX */
+#error "there's no appropriate type for u_int16_t"
+#endif
+#define HAVE_U_INT16_T 1
+#define HAVE_INT16_T 1
+
+#endif /* HAVE_U_INT16_T */
+
+#ifndef HAVE_U_INT32_T
+
+#if SIZEOF_INT == 4
+typedef unsigned int u_int32_t;
+typedef signed int int32_t;
+#elif SIZEOF_LONG == 4
+typedef unsigned long u_int32_t;
+typedef signed long int32_t;
+#elif SIZEOF_SHORT == 4
+typedef unsigned short u_int32_t;
+typedef signed short int32_t;
+#else /* XXX */
+#error "there's no appropriate type for u_int32_t"
+#endif
+#define HAVE_U_INT32_T 1
+#define HAVE_INT32_T 1
+
+#endif /* HAVE_U_INT32_T */
+
+#endif /* _BITTYPES_H */
diff --git a/AppleWin/source/Tfe/Bpf.h b/AppleWin/source/Tfe/Bpf.h
new file mode 100644
index 00000000..0acfc7d3
--- /dev/null
+++ b/AppleWin/source/Tfe/Bpf.h
@@ -0,0 +1,516 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)bpf.h 7.1 (Berkeley) 5/7/91
+ *
+ * @(#) $Header$ (LBL)
+ */
+
+#ifndef BPF_MAJOR_VERSION
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BSD style release date */
+#define BPF_RELEASE 199606
+
+typedef int bpf_int32;
+typedef u_int bpf_u_int32;
+
+/*
+ * Alignment macros. BPF_WORDALIGN rounds up to the next
+ * even multiple of BPF_ALIGNMENT.
+ */
+#ifndef __NetBSD__
+#define BPF_ALIGNMENT sizeof(bpf_int32)
+#else
+#define BPF_ALIGNMENT sizeof(long)
+#endif
+#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
+
+#define BPF_MAXINSNS 512
+#define BPF_MAXBUFSIZE 0x8000
+#define BPF_MINBUFSIZE 32
+
+/*
+ * Structure for BIOCSETF.
+ */
+struct bpf_program {
+ u_int bf_len;
+ struct bpf_insn *bf_insns;
+};
+
+/*
+ * Struct returned by BIOCGSTATS.
+ */
+struct bpf_stat {
+ u_int bs_recv; /* number of packets received */
+ u_int bs_drop; /* number of packets dropped */
+};
+
+/*
+ * Struct return by BIOCVERSION. This represents the version number of
+ * the filter language described by the instruction encodings below.
+ * bpf understands a program iff kernel_major == filter_major &&
+ * kernel_minor >= filter_minor, that is, if the value returned by the
+ * running kernel has the same major number and a minor number equal
+ * equal to or less than the filter being downloaded. Otherwise, the
+ * results are undefined, meaning an error may be returned or packets
+ * may be accepted haphazardly.
+ * It has nothing to do with the source code version.
+ */
+struct bpf_version {
+ u_short bv_major;
+ u_short bv_minor;
+};
+/* Current version number of filter architecture. */
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+/*
+ * BPF ioctls
+ *
+ * The first set is for compatibility with Sun's pcc style
+ * header files. If your using gcc, we assume that you
+ * have run fixincludes so the latter set should work.
+ */
+#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
+#define BIOCGBLEN _IOR(B,102, u_int)
+#define BIOCSBLEN _IOWR(B,102, u_int)
+#define BIOCSETF _IOW(B,103, struct bpf_program)
+#define BIOCFLUSH _IO(B,104)
+#define BIOCPROMISC _IO(B,105)
+#define BIOCGDLT _IOR(B,106, u_int)
+#define BIOCGETIF _IOR(B,107, struct ifreq)
+#define BIOCSETIF _IOW(B,108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW(B,109, struct timeval)
+#define BIOCGRTIMEOUT _IOR(B,110, struct timeval)
+#define BIOCGSTATS _IOR(B,111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW(B,112, u_int)
+#define BIOCVERSION _IOR(B,113, struct bpf_version)
+#define BIOCSTCPF _IOW(B,114, struct bpf_program)
+#define BIOCSUDPF _IOW(B,115, struct bpf_program)
+#else
+#define BIOCGBLEN _IOR('B',102, u_int)
+#define BIOCSBLEN _IOWR('B',102, u_int)
+#define BIOCSETF _IOW('B',103, struct bpf_program)
+#define BIOCFLUSH _IO('B',104)
+#define BIOCPROMISC _IO('B',105)
+#define BIOCGDLT _IOR('B',106, u_int)
+#define BIOCGETIF _IOR('B',107, struct ifreq)
+#define BIOCSETIF _IOW('B',108, struct ifreq)
+#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
+#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
+#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
+#define BIOCIMMEDIATE _IOW('B',112, u_int)
+#define BIOCVERSION _IOR('B',113, struct bpf_version)
+#define BIOCSTCPF _IOW('B',114, struct bpf_program)
+#define BIOCSUDPF _IOW('B',115, struct bpf_program)
+#endif
+
+/*
+ * Structure prepended to each packet.
+ */
+struct bpf_hdr {
+ struct timeval bh_tstamp; /* time stamp */
+ bpf_u_int32 bh_caplen; /* length of captured portion */
+ bpf_u_int32 bh_datalen; /* original length of packet */
+ u_short bh_hdrlen; /* length of bpf header (this struct
+ plus alignment padding) */
+};
+/*
+ * Because the structure above is not a multiple of 4 bytes, some compilers
+ * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
+ * Only the kernel needs to know about it; applications use bh_hdrlen.
+ */
+#if defined(KERNEL) || defined(_KERNEL)
+#define SIZEOF_BPF_HDR 18
+#endif
+
+/*
+ * Data-link level type codes.
+ */
+
+/*
+ * These are the types that are the same on all platforms; on other
+ * platforms, a should be supplied that defines the additional
+ * DLT_* codes appropriately for that platform (the BSDs, for example,
+ * should not just pick up this version of "bpf.h"; they should also define
+ * the additional DLT_* codes used by their kernels, as well as the values
+ * defined here - and, if the values they use for particular DLT_ types
+ * differ from those here, they should use their values, not the ones
+ * here).
+ */
+#define DLT_NULL 0 /* no link-layer encapsulation */
+#define DLT_EN10MB 1 /* Ethernet (10Mb) */
+#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
+#define DLT_AX25 3 /* Amateur Radio AX.25 */
+#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
+#define DLT_CHAOS 5 /* Chaos */
+#define DLT_IEEE802 6 /* IEEE 802 Networks */
+#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
+#define DLT_SLIP 8 /* Serial Line IP */
+#define DLT_PPP 9 /* Point-to-point Protocol */
+#define DLT_FDDI 10 /* FDDI */
+
+/*
+ * These are values from the traditional libpcap "bpf.h".
+ * Ports of this to particular platforms should replace these definitions
+ * with the ones appropriate to that platform, if the values are
+ * different on that platform.
+ */
+#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
+#define DLT_RAW 12 /* raw IP */
+
+/*
+ * These are values from BSD/OS's "bpf.h".
+ * These are not the same as the values from the traditional libpcap
+ * "bpf.h"; however, these values shouldn't be generated by any
+ * OS other than BSD/OS, so the correct values to use here are the
+ * BSD/OS values.
+ *
+ * Platforms that have already assigned these values to other
+ * DLT_ codes, however, should give these codes the values
+ * from that platform, so that programs that use these codes will
+ * continue to compile - even though they won't correctly read
+ * files of these types.
+ */
+#ifdef __NetBSD__
+#ifndef DLT_SLIP_BSDOS
+#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
+#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
+#endif
+#else
+#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
+#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
+#endif
+
+#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
+
+/*
+ * These values are defined by NetBSD; other platforms should refrain from
+ * using them for other purposes, so that NetBSD savefiles with link
+ * types of 50 or 51 can be read as this type on all platforms.
+ */
+#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
+#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
+
+/*
+ * Values between 100 and 103 are used in capture file headers as
+ * link-layer types corresponding to DLT_ types that differ
+ * between platforms; don't use those values for new DLT_ new types.
+ */
+
+/*
+ * This value was defined by libpcap 0.5; platforms that have defined
+ * it with a different value should define it here with that value -
+ * a link type of 104 in a save file will be mapped to DLT_C_HDLC,
+ * whatever value that happens to be, so programs will correctly
+ * handle files with that link type regardless of the value of
+ * DLT_C_HDLC.
+ *
+ * The name DLT_C_HDLC was used by BSD/OS; we use that name for source
+ * compatibility with programs written for BSD/OS.
+ *
+ * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
+ * for source compatibility with programs written for libpcap 0.5.
+ */
+#define DLT_C_HDLC 104 /* Cisco HDLC */
+#define DLT_CHDLC DLT_C_HDLC
+
+#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
+
+/*
+ * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
+ * except when it isn't. (I.e., sometimes it's just raw IP, and
+ * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
+ * so that we don't have to worry about the link-layer header.)
+ */
+
+/*
+ * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
+ * with other values.
+ * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
+ * (DLCI, etc.).
+ */
+#define DLT_FRELAY 107
+
+/*
+ * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
+ * that the AF_ type in the link-layer header is in network byte order.
+ *
+ * OpenBSD defines it as 12, but that collides with DLT_RAW, so we
+ * define it as 108 here. If OpenBSD picks up this file, it should
+ * define DLT_LOOP as 12 in its version, as per the comment above -
+ * and should not use 108 as a DLT_ value.
+ */
+#define DLT_LOOP 108
+
+/*
+ * Values between 109 and 112 are used in capture file headers as
+ * link-layer types corresponding to DLT_ types that might differ
+ * between platforms; don't use those values for new DLT_ types
+ * other than the corresponding DLT_ types.
+ */
+
+/*
+ * This is for Linux cooked sockets.
+ */
+#define DLT_LINUX_SLL 113
+
+/*
+ * Apple LocalTalk hardware.
+ */
+#define DLT_LTALK 114
+
+/*
+ * Acorn Econet.
+ */
+#define DLT_ECONET 115
+
+/*
+ * Reserved for use with OpenBSD ipfilter.
+ */
+#define DLT_IPFILTER 116
+
+/*
+ * Reserved for use in capture-file headers as a link-layer type
+ * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD,
+ * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it
+ * in capture-file headers.
+ */
+#define DLT_PFLOG 117
+
+/*
+ * Registered for Cisco-internal use.
+ */
+#define DLT_CISCO_IOS 118
+
+/*
+ * Reserved for 802.11 cards using the Prism II chips, with a link-layer
+ * header including Prism monitor mode information plus an 802.11
+ * header.
+ */
+#define DLT_PRISM_HEADER 119
+
+/*
+ * Reserved for Aironet 802.11 cards, with an Aironet link-layer header
+ * (see Doug Ambrisko's FreeBSD patches).
+ */
+#define DLT_AIRONET_HEADER 120
+
+/*
+ * Reserved for Siemens HiPath HDLC.
+ */
+#define DLT_HHDLC 121
+
+/*
+ * This is for RFC 2625 IP-over-Fibre Channel.
+ *
+ * This is not for use with raw Fibre Channel, where the link-layer
+ * header starts with a Fibre Channel frame header; it's for IP-over-FC,
+ * where the link-layer header starts with an RFC 2625 Network_Header
+ * field.
+ */
+#define DLT_IP_OVER_FC 122
+
+/*
+ * This is for Full Frontal ATM on Solaris with SunATM, with a
+ * pseudo-header followed by an AALn PDU.
+ *
+ * There may be other forms of Full Frontal ATM on other OSes,
+ * with different pseudo-headers.
+ *
+ * If ATM software returns a pseudo-header with VPI/VCI information
+ * (and, ideally, packet type information, e.g. signalling, ILMI,
+ * LANE, LLC-multiplexed traffic, etc.), it should not use
+ * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
+ * and the like don't have to infer the presence or absence of a
+ * pseudo-header and the form of the pseudo-header.
+ */
+#define DLT_SUNATM 123 /* Solaris+SunATM */
+
+/*
+ * Reserved as per request from Kent Dahlgren
+ * for private use.
+ */
+#define DLT_RIO 124 /* RapidIO */
+#define DLT_PCI_EXP 125 /* PCI Express */
+#define DLT_AURORA 126 /* Xilinx Aurora link layer */
+
+/*
+ * For future use with 802.11 captures - defined by AbsoluteValue
+ * Systems to store a number of bits of link-layer information:
+ *
+ * http://www.shaftnet.org/~pizza/software/capturefrm.txt
+ *
+ * but could and arguably should also be used by non-AVS Linux
+ * 802.11 drivers and BSD drivers; that may happen in the future.
+ */
+#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */
+
+/*
+ * Reserved for the TZSP encapsulation, as per request from
+ * Chris Waters
+ * TZSP is a generic encapsulation for any other link type,
+ * which includes a means to include meta-information
+ * with the packet, e.g. signal strength and channel
+ * for 802.11 packets.
+ */
+#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
+
+/*
+ * BSD's ARCNET headers have the source host, destination host,
+ * and type at the beginning of the packet; that's what's handed
+ * up to userland via BPF.
+ *
+ * Linux's ARCNET headers, however, have a 2-byte offset field
+ * between the host IDs and the type; that's what's handed up
+ * to userland via PF_PACKET sockets.
+ *
+ * We therefore have to have separate DLT_ values for them.
+ */
+#define DLT_ARCNET_LINUX 129 /* ARCNET */
+
+/*
+ * The instruction encodings.
+ */
+/* instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define BPF_RVAL(code) ((code) & 0x18)
+#define BPF_A 0x10
+
+/* misc */
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define BPF_TAX 0x00
+#define BPF_TXA 0x80
+
+/*
+ * The instruction data structure.
+ */
+struct bpf_insn {
+ u_short code;
+ u_char jt;
+ u_char jf;
+ bpf_int32 k;
+};
+
+/*
+ * Macros for insn array initializers.
+ */
+#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
+#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
+
+#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
+/*
+ * Systems based on non-BSD kernels don't have ifnet's (or they don't mean
+ * anything if it is in ) and won't work like this.
+ */
+# if __STDC__
+extern void bpf_tap(struct ifnet *, u_char *, u_int);
+extern void bpf_mtap(struct ifnet *, struct mbuf *);
+extern void bpfattach(struct ifnet *, u_int, u_int);
+extern void bpfilterattach(int);
+# else
+extern void bpf_tap();
+extern void bpf_mtap();
+extern void bpfattach();
+extern void bpfilterattach();
+# endif /* __STDC__ */
+#endif /* BSD && (_KERNEL || KERNEL) */
+#if __STDC__ || defined(__cplusplus)
+extern int bpf_validate(struct bpf_insn *, int);
+extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+#else
+extern int bpf_validate();
+extern u_int bpf_filter();
+#endif
+
+/*
+ * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
+ */
+#define BPF_MEMWORDS 16
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleWin/source/Tfe/Ip6_misc.h b/AppleWin/source/Tfe/Ip6_misc.h
new file mode 100644
index 00000000..6714f0ed
--- /dev/null
+++ b/AppleWin/source/Tfe/Ip6_misc.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 1993, 1994, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header$ (LBL)
+ */
+
+/*
+ * This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows
+ */
+
+#include
+
+#ifndef __MINGW32__
+#include
+#endif /* __MINGW32__ */
+
+#define IN_MULTICAST(a) IN_CLASSD(a)
+
+#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xe0000000) == 0xe0000000)
+
+#define IN_LOOPBACKNET 127
+
+#ifdef __MINGW32__
+/* IPv6 address */
+struct in6_addr
+ {
+ union
+ {
+ u_int8_t u6_addr8[16];
+ u_int16_t u6_addr16[8];
+ u_int32_t u6_addr32[4];
+ } in6_u;
+#define s6_addr in6_u.u6_addr8
+#define s6_addr16 in6_u.u6_addr16
+#define s6_addr32 in6_u.u6_addr32
+#define s6_addr64 in6_u.u6_addr64
+ };
+
+#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
+#endif /* __MINGW32__ */
+
+
+#ifdef __MINGW32__
+typedef unsigned short sa_family_t;
+
+#define __SOCKADDR_COMMON(sa_prefix) \
+ sa_family_t sa_prefix##family
+
+/* Ditto, for IPv6. */
+struct sockaddr_in6
+ {
+ __SOCKADDR_COMMON (sin6_);
+ u_int16_t sin6_port; /* Transport layer port # */
+ u_int32_t sin6_flowinfo; /* IPv6 flow information */
+ struct in6_addr sin6_addr; /* IPv6 address */
+ };
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
+ (((u_int32_t *) (a))[2] == htonl (0xffff)))
+
+#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000))
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
+ ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
+#endif /* __MINGW32__ */
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+/*
+ * IPV6 extension headers
+ */
+#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
+#define IPPROTO_IPV6 41 /* IPv6 header. */
+#define IPPROTO_ROUTING 43 /* IPv6 routing header */
+#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
+#define IPPROTO_ESP 50 /* encapsulating security payload */
+#define IPPROTO_AH 51 /* authentication header */
+#define IPPROTO_ICMPV6 58 /* ICMPv6 */
+#define IPPROTO_NONE 59 /* IPv6 no next header */
+#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
+#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */
+
+#define IPV6_RTHDR_TYPE_0 0
+
+/* Option types and related macros */
+#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
+#define IP6OPT_PADN 0x01 /* 00 0 00001 */
+#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
+#define IP6OPT_JUMBO_LEN 6
+#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */
+
+#define IP6OPT_RTALERT_LEN 4
+#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
+#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
+#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
+#define IP6OPT_MINLEN 2
+
+#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
+#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
+#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
+#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
+#define IP6OPT_EID 0x8a /* 10 0 01010 */
+
+#define IP6OPT_TYPE(o) ((o) & 0xC0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xC0
+
+#define IP6OPT_MUTABLE 0x20
+
+
+#ifdef __MINGW32__
+#ifndef EAI_ADDRFAMILY
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+#endif
+#endif /* __MINGW32__ */
diff --git a/AppleWin/source/Tfe/Pcap-stdinc.h b/AppleWin/source/Tfe/Pcap-stdinc.h
new file mode 100644
index 00000000..fcb28966
--- /dev/null
+++ b/AppleWin/source/Tfe/Pcap-stdinc.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2002
+ * Politecnico di Torino. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the Politecnico
+ * di Torino, and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header$ (LBL)
+ */
+
+#define SIZEOF_CHAR 1
+#define SIZEOF_SHORT 2
+#define SIZEOF_INT 4
+
+#define _WINSOCKAPI_
+#include
+
+#include
+#include "bittypes.h"
+#include
+#include
+
+#ifndef __MINGW32__
+#include "IP6_misc.h"
+#endif
+
+#define caddr_t char*
+
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+
diff --git a/AppleWin/source/Tfe/Pcap.h b/AppleWin/source/Tfe/Pcap.h
new file mode 100644
index 00000000..52d958fb
--- /dev/null
+++ b/AppleWin/source/Tfe/Pcap.h
@@ -0,0 +1,273 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header$ (LBL)
+ */
+
+#ifndef lib_pcap_h
+#define lib_pcap_h
+
+#ifdef WIN32
+/* RGJ Changed it to "pcap-stdinc.h" for AppleWin */
+#include "pcap-stdinc.h"
+#else /* WIN32 */
+#include
+#include
+#endif /* WIN32 */
+
+/* RGJ Changed it to "bpf.h" for AppleWin */
+#include "bpf.h"
+
+#include
+
+#ifdef REMOTE
+ // We have to define the SOCKET here, although it has been defined in sockutils.h
+ // This is to avoid the distribution of the 'sockutils.h' file around
+ // (for example in the WinPcap developer's pack)
+ #ifndef SOCKET
+ #ifdef WIN32
+ #define SOCKET unsigned int
+ #else
+ #define SOCKET int
+ #endif
+ #endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PCAP_VERSION_MAJOR 2
+#define PCAP_VERSION_MINOR 4
+
+#define PCAP_ERRBUF_SIZE 256
+
+/*
+ * Compatibility for systems that have a bpf.h that
+ * predates the bpf typedefs for 64-bit support.
+ */
+#if BPF_RELEASE - 0 < 199406
+typedef int bpf_int32;
+typedef u_int bpf_u_int32;
+#endif
+
+typedef struct pcap pcap_t;
+typedef struct pcap_dumper pcap_dumper_t;
+typedef struct pcap_if pcap_if_t;
+typedef struct pcap_addr pcap_addr_t;
+
+/*
+ * The first record in the file contains saved values for some
+ * of the flags used in the printout phases of tcpdump.
+ * Many fields here are 32 bit ints so compilers won't insert unwanted
+ * padding; these files need to be interchangeable across architectures.
+ *
+ * Do not change the layout of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure).
+ *
+ * Also, do not change the interpretation of any of the members of this
+ * structure, in any way (this includes using values other than
+ * LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
+ * field).
+ *
+ * Instead:
+ *
+ * introduce a new structure for the new format, if the layout
+ * of the structure changed;
+ *
+ * send mail to "tcpdump-workers@tcpdump.org", requesting a new
+ * magic number for your new capture file format, and, when
+ * you get the new magic number, put it in "savefile.c";
+ *
+ * use that magic number for save files with the changed file
+ * header;
+ *
+ * make the code in "savefile.c" capable of reading files with
+ * the old file header as well as files with the new file header
+ * (using the magic number to determine the header format).
+ *
+ * Then supply the changes to "patches@tcpdump.org", so that future
+ * versions of libpcap and programs that use it (such as tcpdump) will
+ * be able to read your new capture file format.
+ */
+struct pcap_file_header {
+ bpf_u_int32 magic;
+ u_short version_major;
+ u_short version_minor;
+ bpf_int32 thiszone; /* gmt to local correction */
+ bpf_u_int32 sigfigs; /* accuracy of timestamps */
+ bpf_u_int32 snaplen; /* max length saved portion of each pkt */
+ bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
+};
+
+/*
+ * Each packet in the dump file is prepended with this generic header.
+ * This gets around the problem of different headers for different
+ * packet interfaces.
+ */
+struct pcap_pkthdr {
+ struct timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+};
+
+/*
+ * As returned by the pcap_stats()
+ */
+struct pcap_stat {
+ u_int ps_recv; /* number of packets received */
+ u_int ps_drop; /* number of packets dropped */
+ u_int ps_ifdrop; /* drops by interface XXX not yet supported */
+#ifdef REMOTE
+#ifdef WIN32
+// u_int bs_capt; /* number of packets that reach the application */
+#endif /* WIN32 */
+ u_int ps_capt; /* number of packets that reach the application; please get rid off the Win32 ifdef */
+ u_int ps_sent; /* number of packets sent by the server on the network */
+ u_int ps_netdrop; /* number of packets lost on the network */
+#endif
+};
+
+/*
+ * Item in a list of interfaces.
+ */
+struct pcap_if {
+ struct pcap_if *next;
+ char *name; /* name to hand to "pcap_open_live()" */
+ char *description; /* textual description of interface, or NULL */
+ struct pcap_addr *addresses;
+ bpf_u_int32 flags; /* PCAP_IF_ interface flags */
+};
+
+#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
+
+/*
+ * Representation of an interface address.
+ */
+struct pcap_addr {
+ struct pcap_addr *next;
+ struct sockaddr *addr; /* address */
+ struct sockaddr *netmask; /* netmask for that address */
+ struct sockaddr *broadaddr; /* broadcast address for that address */
+ struct sockaddr *dstaddr; /* P2P destination address for that address */
+};
+
+typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
+
+char *pcap_lookupdev(char *);
+int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+pcap_t *pcap_open_live(const char *, int, int, int, char *);
+pcap_t *pcap_open_dead(int, int);
+pcap_t *pcap_open_offline(const char *, char *);
+void pcap_close(pcap_t *);
+int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
+int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
+const u_char*
+ pcap_next(pcap_t *, struct pcap_pkthdr *);
+int pcap_stats(pcap_t *, struct pcap_stat *);
+int pcap_setfilter(pcap_t *, struct bpf_program *);
+int pcap_getnonblock(pcap_t *, char *);
+int pcap_setnonblock(pcap_t *, int, char *);
+void pcap_perror(pcap_t *, char *);
+char *pcap_strerror(int);
+char *pcap_geterr(pcap_t *);
+int pcap_compile(pcap_t *, struct bpf_program *, char *, int,
+ bpf_u_int32);
+int pcap_compile_nopcap(int, int, struct bpf_program *,
+ char *, int, bpf_u_int32);
+void pcap_freecode(struct bpf_program *);
+int pcap_datalink(pcap_t *);
+int pcap_list_datalinks(pcap_t *, int **);
+int pcap_set_datalink(pcap_t *, int);
+int pcap_datalink_name_to_val(const char *);
+const char *pcap_datalink_val_to_name(int);
+int pcap_snapshot(pcap_t *);
+int pcap_is_swapped(pcap_t *);
+int pcap_major_version(pcap_t *);
+int pcap_minor_version(pcap_t *);
+
+/* XXX */
+FILE *pcap_file(pcap_t *);
+int pcap_fileno(pcap_t *);
+
+pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
+int pcap_dump_flush(pcap_dumper_t *);
+void pcap_dump_close(pcap_dumper_t *);
+void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
+
+int pcap_findalldevs(pcap_if_t **, char *);
+void pcap_freealldevs(pcap_if_t *);
+
+/* To avoid callback, this returns one packet at a time */
+int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data);
+
+/* XXX this guy lives in the bpf tree */
+u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+int bpf_validate(struct bpf_insn *f, int len);
+char *bpf_image(struct bpf_insn *, int);
+void bpf_dump(struct bpf_program *, int);
+
+#ifdef WIN32
+/*
+ * Win32 definitions
+ */
+
+int pcap_setbuff(pcap_t *p, int dim);
+int pcap_setmode(pcap_t *p, int mode);
+int pcap_sendpacket(pcap_t *p, u_char *buf, int size);
+int pcap_setmintocopy(pcap_t *p, int size);
+
+#ifdef WPCAP
+/* Include file with the wpcap-specific extensions */
+#include
+#endif
+
+#define MODE_CAPT 0
+#define MODE_STAT 1
+#define MODE_MON 2
+
+#endif /* WIN32 */
+
+#ifdef REMOTE
+/* Includes most of the public stuff that is needed for the remote capture */
+#include "remote-ext.h"
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/AppleWin/source/Tfe/Tfe.cpp b/AppleWin/source/Tfe/Tfe.cpp
new file mode 100644
index 00000000..a0149b91
--- /dev/null
+++ b/AppleWin/source/Tfe/Tfe.cpp
@@ -0,0 +1,1533 @@
+/*
+ * tfe.c - TFE ("The final ethernet") emulation.
+ *
+ * Written by
+ * Spiro Trikaliotis
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+
+#include
+#include
+#include
+#include
+#ifdef DOS_TFE
+#include
+#endif
+
+#include "tfe.h"
+#include "tfearch.h"
+#include "tfesupp.h"
+
+
+/**/
+/** #define TFE_DEBUG_DUMP 1 **/
+
+/* #define TFE_DEBUG_FRAMES - might be defined in TFE.H! */
+
+#define TFE_DEBUG_WARN 1 /* this should not be deactivated */
+#define TFE_DEBUG_INIT 1
+/** #define TFE_DEBUG_LOAD 1 **/
+/** #define TFE_DEBUG_STORE 1 **/
+/**/
+
+/* ------------------------------------------------------------------------- */
+/* variables needed */
+
+/*
+ This variable is used when we need to postpone the initialization
+ because tfe_init() is not yet called
+*/
+static int should_activate = 0;
+
+
+static int init_tfe_flag = 0;
+
+/* status which received packages to accept
+ This is used in tfe_should_accept().
+*/
+static BYTE tfe_ia_mac[6];
+
+/* remember the value of the hash mask */
+static DWORD tfe_hash_mask[2];
+
+static int tfe_recv_broadcast = 0; /* broadcast */
+static int tfe_recv_mac = 0; /* individual address (IA) */
+static int tfe_recv_multicast = 0; /* multicast if address passes the hash filter */
+static int tfe_recv_correct = 0; /* accept correct frames */
+static int tfe_recv_promiscuous = 0; /* promiscuous mode */
+static int tfe_recv_hashfilter = 0; /* accept if IA passes the hash filter */
+
+
+#ifdef TFE_DEBUG_WARN
+/* remember if the TXCMD has been completed before a new one is issued */
+static int tfe_started_tx = 0;
+#endif
+
+
+/* Flag: Can we even use TFE, or is the hardware not available? */
+static int tfe_cannot_use = 0;
+
+/* Flag: Do we have the TFE enabled? */
+int tfe_enabled = 0;
+
+/* Flag: Do we use the "original" memory map or the memory map of the RR-Net? */
+//static int tfe_as_rr_net = 0;
+
+char *tfe_interface = NULL;
+
+/* TFE registers */
+/* these are the 8 16-bit-ports for "I/O space configuration"
+ (see 4.10 on page 75 of cs8900a-4.pdf, the cs8900a data sheet)
+
+ REMARK: The TFE operatoes the cs8900a in IO space configuration, as
+ it generates I/OW and I/OR signals.
+*/
+#define TFE_COUNT_IO_REGISTER 0x10 /* we have 16 I/O register */
+
+static BYTE *tfe = NULL;
+/*
+ RW: RXTXDATA = DE00/DE01
+ RW: RXTXDATA2 = DE02/DE03 (for 32-bit-operation)
+ -W: TXCMD = DE04/DE05 (TxCMD, Transmit Command) mapped to PP + 0144 (Reg. 9, Sec. 4.4, page 46)
+ -W: TXLENGTH = DE06/DE07 (TxLenght, Transmit Length) mapped to PP + 0146
+ R-: INTSTQUEUE = DE08/DE09 (Interrupt Status Queue) mapped to PP + 0120 (ISQ, Sec. 5.1, page 78)
+ RW: PP_PTR = DE0A/DE0B (PacketPage Pointer) (see. page 75p: Read -011.---- ----.----)
+ RW: PP_DATA0 = DE0C/DE0D (PacketPage Data (Port 0))
+ RW: PP_DATA1 = DE0E/DE0F (PacketPage Data (Port 1)) (for 32 bit only)
+*/
+
+#define TFE_ADDR_RXTXDATA 0x00 /* RW */
+#define TFE_ADDR_RXTXDATA2 0x02 /* RW 32 bit only! */
+#define TFE_ADDR_TXCMD 0x04 /* -W Maps to PP+0144 */
+#define TFE_ADDR_TXLENGTH 0x06 /* -W Maps to PP+0146 */
+#define TFE_ADDR_INTSTQUEUE 0x08 /* R- Interrupt status queue, maps to PP + 0120 */
+#define TFE_ADDR_PP_PTR 0x0a /* RW PacketPage Pointer */
+#define TFE_ADDR_PP_DATA 0x0c /* RW PacketPage Data, Port 0 */
+#define TFE_ADDR_PP_DATA2 0x0e /* RW PacketPage Data, Port 1 - 32 bit only */
+
+/* Makros for reading and writing the visible TFE register: */
+#define GET_TFE_8( _xxx_ ) \
+ ( assert(_xxx_> 8) & 0xff; \
+ } while (0)
+
+/* The PacketPage register */
+/* note: The locations 0 to MAX_PACKETPAGE_ARRAY-1 are handled in this array. */
+
+#define MAX_PACKETPAGE_ARRAY 0x1000 /* 4 KB */
+
+static BYTE *tfe_packetpage = NULL;
+
+static WORD tfe_packetpage_ptr = 0;
+
+/* Makros for reading and writing the PacketPage register: */
+
+#define GET_PP_8( _xxx_ ) \
+ (assert(_xxx_> 8) & 0xFF; \
+ } while (0)
+
+#define SET_PP_32( _xxx_, _val_ ) \
+ do { \
+ assert(_xxx_> 8) & 0xFF; \
+ tfe_packetpage[_xxx_+2] = (_val_>>16) & 0xFF; \
+ tfe_packetpage[_xxx_+3] = (_val_>>24) & 0xFF; \
+ } while (0)
+
+
+/* The packetpage register: see p. 39f */
+#define TFE_PP_ADDR_PRODUCTID 0x0000 /* R- - 4.3., p. 41 */
+#define TFE_PP_ADDR_IOBASE 0x0020 /* i RW - 4.3., p. 41 - 4.7., p. 72 */
+#define TFE_PP_ADDR_INTNO 0x0022 /* i RW - 3.2., p. 17 - 4.3., p. 41 */
+#define TFE_PP_ADDR_DMA_CHAN 0x0024 /* i RW - 3.2., p. 17 - 4.3., p. 41 */
+#define TFE_PP_ADDR_DMA_SOF 0x0026 /* ? R- - 4.3., p. 41 - 5.4., p. 89 */
+#define TFE_PP_ADDR_DMA_FC 0x0028 /* ? R- - 4.3., p. 41, "Receive DMA" */
+#define TFE_PP_ADDR_RXDMA_BC 0x002a /* ? R- - 4.3., p. 41 - 5.4., p. 89 */
+#define TFE_PP_ADDR_MEMBASE 0x002c /* i RW - 4.3., p. 41 - 4.9., p. 73 */
+#define TFE_PP_ADDR_BPROM_BASE 0x0030 /* i RW - 3.6., p. 24 - 4.3., p. 41 */
+#define TFE_PP_ADDR_BPROM_MASK 0x0034 /* i RW - 3.6., p. 24 - 4.3., p. 41 */
+/* 0x0038 - 0x003F: reserved */
+#define TFE_PP_ADDR_EEPROM_CMD 0x0040 /* i RW - 3.5., p. 23 - 4.3., p. 41 */
+#define TFE_PP_ADDR_EEPROM_DATA 0x0042 /* i RW - 3.5., p. 23 - 4.3., p. 41 */
+/* 0x0044 - 0x004F: reserved */
+#define TFE_PP_ADDR_REC_FRAME_BC 0x0050 /* RW - 4.3., p. 41 - 5.2.9., p. 86 */
+/* 0x0052 - 0x00FF: reserved */
+#define TFE_PP_ADDR_CONF_CTRL 0x0100 /* - RW - 4.4., p. 46; see below */
+#define TFE_PP_ADDR_STATUS_EVENT 0x0120 /* - R- - 4.4., p. 46; see below */
+/* 0x0140 - 0x0143: reserved */
+#define TFE_PP_ADDR_TXCMD 0x0144 /* # -W - 4.5., p. 70 - 5.7., p. 98 */
+#define TFE_PP_ADDR_TXLENGTH 0x0146 /* # -W - 4.5., p. 70 - 5.7., p. 98 */
+/* 0x0148 - 0x014F: reserved */
+#define TFE_PP_ADDR_LOG_ADDR_FILTER 0x0150 /* RW - 4.6., p. 71 - 5.3., p. 86 */
+#define TFE_PP_ADDR_MAC_ADDR 0x0158 /* # RW - 4.6., p. 71 - 5.3., p. 86 */
+/* 0x015E - 0x03FF: reserved */
+#define TFE_PP_ADDR_RXSTATUS 0x0400 /* R- - 4.7., p. 72 - 5.2., p. 78 */
+#define TFE_PP_ADDR_RXLENGTH 0x0402 /* R- - 4.7., p. 72 - 5.2., p. 78 */
+#define TFE_PP_ADDR_RX_FRAMELOC 0x0404 /* R- - 4.7., p. 72 - 5.2., p. 78 */
+/* here, the received frame is stored */
+#define TFE_PP_ADDR_TX_FRAMELOC 0x0A00 /* -W - 4.7., p. 72 - 5.7., p. 98 */
+/* here, the frame to transmit is stored */
+#define TFE_PP_ADDR_END 0x1000 /* memory to TFE_PP_ADDR_END-1 is used */
+
+
+/* TFE_PP_ADDR_CONF_CTRL is subdivided: */
+#define TFE_PP_ADDR_CC_RXCFG 0x0102 /* # RW - 4.4.6., p. 52 - 0003 */
+#define TFE_PP_ADDR_CC_RXCTL 0x0104 /* # RW - 4.4.8., p. 54 - 0005 */
+#define TFE_PP_ADDR_CC_TXCFG 0x0106 /* RW - 4.4.9., p. 55 - 0007 */
+#define TFE_PP_ADDR_CC_TXCMD 0x0108 /* R- - 4.4.11., p. 57 - 0009 */
+#define TFE_PP_ADDR_CC_BUFCFG 0x010A /* RW - 4.4.12., p. 58 - 000B */
+#define TFE_PP_ADDR_CC_LINECTL 0x0112 /* # RW - 4.4.16., p. 62 - 0013 */
+#define TFE_PP_ADDR_CC_SELFCTL 0x0114 /* RW - 4.4.18., p. 64 - 0015 */
+#define TFE_PP_ADDR_CC_BUSCTL 0x0116 /* RW - 4.4.20., p. 66 - 0017 */
+#define TFE_PP_ADDR_CC_TESTCTL 0x0118 /* RW - 4.4.22., p. 68 - 0019 */
+
+/* TFE_PP_ADDR_STATUS_EVENT is subdivided: */
+#define TFE_PP_ADDR_SE_ISQ 0x0120 /* R- - 4.4.5., p. 51 - 0000 */
+#define TFE_PP_ADDR_SE_RXEVENT 0x0124 /* # R- - 4.4.7., p. 53 - 0004 */
+#define TFE_PP_ADDR_SE_TXEVENT 0x0128 /* R- - 4.4.10., p. 56 - 0008 */
+#define TFE_PP_ADDR_SE_BUFEVENT 0x012C /* R- - 4.4.13., p. 59 - 000C */
+#define TFE_PP_ADDR_SE_RXMISS 0x0130 /* R- - 4.4.14., p. 60 - 0010 */
+#define TFE_PP_ADDR_SE_TXCOL 0x0132 /* R- - 4.4.15., p. 61 - 0012 */
+#define TFE_PP_ADDR_SE_LINEST 0x0134 /* R- - 4.4.17., p. 63 - 0014 */
+#define TFE_PP_ADDR_SE_SELFST 0x0136 /* R- - 4.4.19., p. 65 - 0016 */
+#define TFE_PP_ADDR_SE_BUSST 0x0138 /* # R- - 4.4.21., p. 67 - 0018 */
+#define TFE_PP_ADDR_SE_TDR 0x013C /* R- - 4.4.23., p. 69 - 001C */
+
+
+/* ------------------------------------------------------------------------- */
+/* more variables needed */
+
+static WORD txcollect_buffer = TFE_PP_ADDR_TX_FRAMELOC;
+static WORD rx_buffer = TFE_PP_ADDR_RXSTATUS;
+
+
+
+/* ------------------------------------------------------------------------- */
+/* some parameter definitions */
+
+#define MAX_TXLENGTH 1518
+#define MIN_TXLENGTH 4
+
+#define MAX_RXLENGTH 1518
+#define MIN_RXLENGTH 64
+
+
+/* ------------------------------------------------------------------------- */
+/* debugging functions */
+
+#ifdef TFE_DEBUG_FRAMES
+
+static int TfeDebugMaxFrameLengthToDump = 150;
+
+char *debug_outbuffer(const int length, const unsigned char * const buffer)
+{
+#define MAXLEN_DEBUG 1600
+
+ int i;
+ static char outbuffer[MAXLEN_DEBUG*4+1];
+ char *p = outbuffer;
+
+ assert( TfeDebugMaxFrameLengthToDump <= MAXLEN_DEBUG );
+
+ *p = 0;
+
+ for (i=0; i=length)
+ break;
+
+ sprintf( p, "%02X%c", buffer[i], ((i+1)%16==0)?'*':(((i+1)%8==0)?'-':' '));
+ p+=3;
+ }
+
+ return outbuffer;
+}
+
+#endif
+
+
+#ifdef TFE_DEBUG_DUMP
+
+#define NUMBER_PER_LINE 8
+
+static
+void tfe_debug_output_general( char *what, WORD (*getFunc)(int), int count )
+{
+ int i;
+ char buffer[7+(6*NUMBER_PER_LINE)+2];
+
+ if(g_fh) fprintf(g_fh, "%s contents:", what );
+ for (i=0; i=6); /* we need at least 6 octets since the DA has this length */
+
+ /* first of all, delete any status */
+ *phashed = 0;
+ *phash_index = 0;
+ *pcorrect_mac = 0;
+ *pbroadcast = 0;
+ *pmulticast = 0;
+
+#ifdef TFE_DEBUG_FRAMES
+ if(g_fh) fprintf(g_fh, "tfe_should_accept called with %02X:%02X:%02X:%02X:%02X:%02X, length=%4u and buffer %s",
+ tfe_ia_mac[0], tfe_ia_mac[1], tfe_ia_mac[2],
+ tfe_ia_mac[3], tfe_ia_mac[4], tfe_ia_mac[5],
+ length,
+ debug_outbuffer(length, buffer)
+ );
+#endif
+
+
+ if ( buffer[0]==tfe_ia_mac[0]
+ && buffer[1]==tfe_ia_mac[1]
+ && buffer[2]==tfe_ia_mac[2]
+ && buffer[3]==tfe_ia_mac[3]
+ && buffer[4]==tfe_ia_mac[4]
+ && buffer[5]==tfe_ia_mac[5]
+ ) {
+ /* this is our individual address (IA) */
+
+ *pcorrect_mac = 1;
+
+ /* if we don't want "correct MAC", we might have the chance
+ * that this address fits the hash index
+ */
+ if (tfe_recv_mac || tfe_recv_promiscuous)
+ return(1);
+ }
+
+ if ( buffer[0]==0xFF
+ && buffer[1]==0xFF
+ && buffer[2]==0xFF
+ && buffer[3]==0xFF
+ && buffer[4]==0xFF
+ && buffer[5]==0xFF
+ ) {
+ /* this is a broadcast address */
+ *pbroadcast = 1;
+
+ /* broadcasts cannot be accepted by the hash filter */
+ return((tfe_recv_broadcast || tfe_recv_promiscuous) ? 1 : 0);
+ }
+
+ /* now check if DA passes the hash filter */
+ /* RGJ added (const char *) for AppleWin */
+ hashreg = (~crc32_buf((const char *)buffer,6) >> 26) & 0x3F;
+
+ *phashed = (tfe_hash_mask[(hashreg>=32)?1:0] & (1 << (hashreg&0x1F))) ? 1 : 0;
+ if (*phashed) {
+ *phash_index = hashreg;
+
+ if (buffer[0] & 0x80) {
+ /* we have a multicast address */
+ *pmulticast = 1;
+
+ /* if the multicast address fits into the hash filter,
+ * the hashed bit has to be clear
+ */
+ *phashed = 0;
+
+ return((tfe_recv_multicast || tfe_recv_promiscuous) ? 1 : 0);
+ }
+ return((tfe_recv_hashfilter || tfe_recv_promiscuous) ? 1 : 0);
+ }
+
+ return(tfe_recv_promiscuous ? 1 : 0);
+}
+
+#ifdef TFE_DEBUG_FRAMES
+ #undef return
+#endif
+
+static
+WORD tfe_receive(void)
+{
+ WORD ret_val = 0x0004;
+
+ BYTE buffer[MAX_RXLENGTH];
+
+ int len;
+ int hashed;
+ int hash_index;
+ int rx_ok;
+ int correct_mac;
+ int broadcast;
+ int multicast;
+ int crc_error;
+
+ int newframe;
+
+ int ready;
+
+#ifdef TFE_DEBUG_FRAMES
+ if(g_fh) fprintf( g_fh, "");
+#endif
+
+ do {
+ len = MAX_RXLENGTH;
+
+ ready = 1 ; /* assume we will find a good frame */
+
+ newframe = tfe_arch_receive(
+ buffer, /* where to store a frame */
+ &len, /* length of received frame */
+ &hashed, /* set if the dest. address is accepted by the hash filter */
+ &hash_index, /* hash table index if hashed == TRUE */
+ &rx_ok, /* set if good CRC and valid length */
+ &correct_mac, /* set if dest. address is exactly our IA */
+ &broadcast, /* set if dest. address is a broadcast address */
+ &crc_error /* set if received frame had a CRC error */
+ );
+
+ assert((len&1) == 0); /* length has to be even! */
+
+ if (newframe) {
+ if (hashed || correct_mac || broadcast) {
+ /* we already know the type of frame: Trust it! */
+#ifdef TFE_DEBUG_FRAMES
+ if(g_fh) fprintf( g_fh, "+++ tfe_receive(): *** hashed=%u, correct_mac=%u, "
+ "broadcast=%u", hashed, correct_mac, broadcast);
+#endif
+ }
+ else {
+ /* determine ourself the type of frame */
+ if (!tfe_should_accept(buffer,
+ len, &hashed, &hash_index, &correct_mac, &broadcast, &multicast)) {
+
+ /* if we should not accept this frame, just do nothing
+ * now, look for another one */
+ ready = 0; /* try another frame */
+ continue;
+ }
+ }
+
+
+ /* we did receive a frame, return that status */
+ ret_val |= rx_ok ? 0x0100 : 0;
+ ret_val |= multicast ? 0x0200 : 0;
+
+ if (!multicast) {
+ ret_val |= hashed ? 0x0040 : 0;
+ }
+
+ if (hashed && rx_ok) {
+ /* we have the 2nd, special format with hash index: */
+ assert(hash_index < 64);
+ ret_val |= hash_index << 9;
+ }
+ else {
+ /* we have the regular format */
+ ret_val |= correct_mac ? 0x0400 : 0;
+ ret_val |= broadcast ? 0x0800 : 0;
+ ret_val |= crc_error ? 0x1000 : 0;
+ ret_val |= (lenMAX_RXLENGTH) ? 0x4000 : 0;
+ }
+
+ /* discard any octets that are beyond the MAX_RXLEN */
+ if (len>MAX_RXLENGTH) {
+ len = MAX_RXLENGTH;
+ }
+
+ if (rx_ok) {
+ int i;
+
+ /* set relevant parts of the PP area to correct values */
+ SET_PP_16(TFE_PP_ADDR_RXLENGTH, len);
+
+ for (i=0;iMAX_TXLENGTH)
+ || ((txlen>MAX_TXLENGTH-4) && (!(txcmd&0x1000)))
+ || (txlenMAX_TXLENGTH)
+ || ((txlength>MAX_TXLENGTH-4) && (!(txcommand&0x1000)))
+ ) {
+ /* txlength too big, mark an error */
+ SET_PP_16(TFE_PP_ADDR_SE_BUSST, (GET_PP_16(TFE_PP_ADDR_SE_BUSST) | 0x80) & ~0x100);
+ }
+ else {
+ /* all right, signal that we're ready for the next frame */
+ SET_PP_16(TFE_PP_ADDR_SE_BUSST, (GET_PP_16(TFE_PP_ADDR_SE_BUSST) & ~0x80) | 0x100);
+ }
+ }
+ break;
+
+ case TFE_PP_ADDR_LOG_ADDR_FILTER:
+ case TFE_PP_ADDR_LOG_ADDR_FILTER+2:
+ case TFE_PP_ADDR_LOG_ADDR_FILTER+4:
+ case TFE_PP_ADDR_LOG_ADDR_FILTER+6:
+ {
+ unsigned int pos = 8 * (ppaddress - TFE_PP_ADDR_LOG_ADDR_FILTER + oddaddress);
+ DWORD *p = (pos < 32) ? &tfe_hash_mask[0] : &tfe_hash_mask[1];
+
+ *p &= ~(0xFF << pos); /* clear out relevant bits */
+ *p |= GET_PP_8(ppaddress+oddaddress) << pos;
+
+ tfe_arch_set_hashfilter(tfe_hash_mask);
+ }
+ break;
+
+ case TFE_PP_ADDR_MAC_ADDR:
+ case TFE_PP_ADDR_MAC_ADDR+2:
+ case TFE_PP_ADDR_MAC_ADDR+4:
+ /* the MAC address has been changed */
+ tfe_ia_mac[ppaddress-TFE_PP_ADDR_MAC_ADDR+oddaddress] =
+ GET_PP_8(ppaddress+oddaddress);
+ tfe_arch_set_mac(tfe_ia_mac);
+ break;
+ }
+}
+
+/*
+ This is called *before* the relevant octets are read
+*/
+static
+void tfe_sideeffects_read_pp(WORD ppaddress)
+{
+ assert((ppaddress & 1) == 0);
+
+ switch (ppaddress)
+ {
+ case TFE_PP_ADDR_SE_RXEVENT:
+ /* reading this before all octets of the frame are read
+ performs an "implied skip" */
+ {
+ WORD ret_val = tfe_receive();
+
+ /*
+ RXSTATUS and RXEVENT are the same, except that RXSTATUS buffers
+ the old value while RXEVENT sets a new value whenever it is called
+ */
+ SET_PP_16(TFE_PP_ADDR_RXSTATUS, ret_val);
+ SET_PP_16(TFE_PP_ADDR_SE_RXEVENT, ret_val);
+ }
+
+ break;
+
+ case TFE_PP_ADDR_SE_BUSST:
+ break;
+
+ case TFE_PP_ADDR_TXCMD:
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh, "WARNING! Read write-only register TFE_PP_ADDR_TXCMD: IGNORED");
+#endif
+ break;
+
+ case TFE_PP_ADDR_TXLENGTH:
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh, "WARNING! Read write-only register TFE_PP_ADDR_TXLENGTH: IGNORED");
+#endif
+ break;
+ }
+}
+
+
+void tfe_proceed_rx_buffer(int oddaddress) {
+ /*
+ According to the CS8900 spec, the handling is the following:
+ first read H, then L, then H, then L.
+ Now, we're inside the RX frame, now, we always get L then H, until the end is reached.
+
+ even odd
+ TFE_PP_ADDR_RXSTATUS: - proceed 1)
+ TFE_PP_ADDR_RXLENGTH: - proceed
+ TFE_PP_ADDR_RX_FRAMELOC: 2),3) -
+ TFE_PP_ADDR_RX_FRAMELOC+2: proceed -
+ TFE_PP_ADDR_RX_FRAMELOC+4: like TFE_PP_ADDR_RX_FRAMELOC+2
+
+ 1) set status "Inside FRAMELOC" FALSE
+ 2) set status "Inside FRAMELOC" TRUE if it is not already
+ 3) if "Inside FRAMELOC", proceed
+
+ */
+
+ static int inside_frameloc;
+ int proceed = 0;
+
+ if (rx_buffer==TFE_PP_ADDR_RX_FRAMELOC+GET_PP_16(TFE_PP_ADDR_RXLENGTH)) {
+ /* we've read all that is available, go to start again */
+ rx_buffer = TFE_PP_ADDR_RXSTATUS;
+ inside_frameloc = 0;
+ }
+ else {
+ switch (rx_buffer) {
+ case TFE_PP_ADDR_RXSTATUS:
+ if (oddaddress) {
+ proceed = 1;
+ inside_frameloc = 0;
+ }
+ break;
+
+ case TFE_PP_ADDR_RXLENGTH:
+ if (oddaddress) {
+ proceed = 1;
+ }
+ break;
+
+ case TFE_PP_ADDR_RX_FRAMELOC:
+ if (oddaddress==0) {
+ if (inside_frameloc) {
+ proceed = 1;
+ }
+ else {
+ inside_frameloc = 1;
+ }
+ }
+ break;
+
+ default:
+ proceed = (oddaddress==0) ? 1 : 0;
+ break;
+ }
+ }
+
+ if (proceed) {
+ SET_TFE_16(TFE_ADDR_RXTXDATA, GET_PP_16(rx_buffer));
+ rx_buffer += 2;
+ }
+}
+
+
+BYTE REGPARM1 tfe_read(WORD ioaddress)
+{
+ BYTE retval;
+
+ assert( tfe );
+ assert( tfe_packetpage );
+
+ assert( ioaddress < 0x10);
+
+ switch (ioaddress) {
+
+ case TFE_ADDR_TXCMD:
+ case TFE_ADDR_TXCMD+1:
+ case TFE_ADDR_TXLENGTH:
+ case TFE_ADDR_TXLENGTH+1:
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh, "WARNING! Reading write-only TFE register $%02X!", ioaddress);
+#endif
+ /* @SRT TODO: Verify with reality */
+ retval = GET_TFE_8(ioaddress);
+ break;
+
+ case TFE_ADDR_RXTXDATA2:
+ case TFE_ADDR_RXTXDATA2+1:
+ case TFE_ADDR_PP_DATA2:
+ case TFE_ADDR_PP_DATA2+1:
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh, "WARNING! Reading not supported TFE register $%02X!", ioaddress);
+#endif
+ /* @SRT TODO */
+ retval = GET_TFE_8(ioaddress);
+ break;
+
+ case TFE_ADDR_PP_DATA:
+ case TFE_ADDR_PP_DATA+1:
+ /* make sure the TFE register have the correct content */
+ {
+ WORD ppaddress = tfe_packetpage_ptr & (MAX_PACKETPAGE_ARRAY-1);
+
+ /* perform side-effects the read may perform */
+ tfe_sideeffects_read_pp( ppaddress );
+
+ /* [3] make sure the data matches the real value - [1] assumes this! */
+ SET_TFE_16( TFE_ADDR_PP_DATA, GET_PP_16(ppaddress) );
+ }
+
+
+#ifdef TFE_DEBUG_LOAD
+ if(g_fh) fprintf(g_fh, "reading PP Ptr: $%04X => $%04X.",
+ tfe_packetpage_ptr, GET_PP_16(tfe_packetpage_ptr) );
+#endif
+
+ retval = GET_TFE_8(ioaddress);
+ break;
+
+ case TFE_ADDR_INTSTQUEUE:
+ case TFE_ADDR_INTSTQUEUE+1:
+ SET_TFE_16( TFE_ADDR_INTSTQUEUE, GET_PP_16(0x0120) );
+ retval = GET_TFE_8(ioaddress);
+ break;
+
+ case TFE_ADDR_RXTXDATA:
+ case TFE_ADDR_RXTXDATA+1:
+ /* we're trying to read a new 16 bit word, get it from the
+ receive buffer
+ */
+ tfe_proceed_rx_buffer(ioaddress & 0x01);
+ retval = GET_TFE_8(ioaddress);
+ break;
+
+ default:
+ retval = GET_TFE_8(ioaddress);
+ break;
+ };
+
+#ifdef TFE_DEBUG_LOAD
+ if(g_fh) fprintf(g_fh, "read [$%02X] => $%02X.", ioaddress, retval);
+#endif
+ return retval;
+}
+
+void REGPARM2 tfe_store(WORD ioaddress, BYTE byte)
+{
+ assert( tfe );
+ assert( tfe_packetpage );
+
+ assert( ioaddress < 0x10);
+
+ switch (ioaddress)
+ {
+ case TFE_ADDR_RXTXDATA:
+ case TFE_ADDR_RXTXDATA+1:
+ SET_PP_8(txcollect_buffer, byte);
+ tfe_sideeffects_write_pp_on_txframe(txcollect_buffer++);
+ break;
+
+ case TFE_ADDR_INTSTQUEUE:
+ case TFE_ADDR_INTSTQUEUE+1:
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh, "WARNING! Writing read-only TFE register $%02X!", ioaddress);
+#endif
+ /* @SRT TODO: Verify with reality */
+ /* do nothing */
+ return;
+
+ case TFE_ADDR_RXTXDATA2:
+ case TFE_ADDR_RXTXDATA2+1:
+ case TFE_ADDR_PP_DATA2:
+ case TFE_ADDR_PP_DATA2+1:
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh, "WARNING! Writing not supported TFE register $%02X!", ioaddress);
+#endif
+ /* do nothing */
+ return;
+
+ case TFE_ADDR_TXCMD:
+ case TFE_ADDR_TXCMD+1:
+ SET_TFE_8(ioaddress, byte);
+ SET_PP_8((ioaddress-TFE_ADDR_TXCMD)+TFE_PP_ADDR_TXCMD, byte); /* perform the mapping to PP+0144 */
+ tfe_sideeffects_write_pp(TFE_PP_ADDR_TXCMD, ioaddress-TFE_ADDR_TXCMD);
+ break;
+
+ case TFE_ADDR_TXLENGTH:
+ case TFE_ADDR_TXLENGTH+1:
+
+ SET_TFE_8(ioaddress, byte);
+ SET_PP_8((ioaddress-TFE_ADDR_TXLENGTH)+TFE_PP_ADDR_TXLENGTH, byte ); /* perform the mapping to PP+0144 */
+
+ tfe_sideeffects_write_pp(TFE_PP_ADDR_TXLENGTH, ioaddress-TFE_ADDR_TXLENGTH);
+ break;
+
+/*
+#define TFE_ADDR_TXCMD 0x04 * -W Maps to PP+0144 *
+#define TFE_ADDR_TXLENGTH 0x06 * -W Maps to PP+0146 *
+#define TFE_ADDR_INTSTQUEUE 0x08 * R- Interrupt status queue, maps to PP + 0120 *
+*/
+ case TFE_ADDR_PP_DATA:
+ case TFE_ADDR_PP_DATA+1:
+
+ /* [2] make sure the data matches the real value - [1] assumes this! */
+ SET_TFE_16(TFE_ADDR_PP_DATA, GET_PP_16(tfe_packetpage_ptr));
+ /* FALL THROUGH */
+
+ default:
+ SET_TFE_8(ioaddress, byte);
+ }
+
+#ifdef TFE_DEBUG_STORE
+ if(g_fh) fprintf(g_fh, "store [$%02X] <= $%02X.", ioaddress, (int)byte);
+#endif
+
+ /* now check if we have to do any side-effects */
+ switch (ioaddress)
+ {
+ case TFE_ADDR_PP_PTR:
+ case TFE_ADDR_PP_PTR+1:
+ tfe_packetpage_ptr = GET_TFE_16(TFE_ADDR_PP_PTR);
+
+#ifdef TFE_DEBUG_STORE
+ if(g_fh) fprintf(g_fh, "set PP Ptr to $%04X.", tfe_packetpage_ptr);
+#endif
+
+ if ((tfe_packetpage_ptr & 1) != 0) {
+
+#ifdef TFE_DEBUG_WARN
+ if(g_fh) fprintf(g_fh,
+ "WARNING! PacketPage register set to odd address $%04X (not allowed!)",
+ tfe_packetpage_ptr );
+#endif /* #ifdef TFE_DEBUG_WARN */
+
+ /* "correct" the address to the next lower address
+ REMARK: I don't know how a real cs8900a will behave in this case,
+ since it is not allowed. Nevertheless, this "correction"
+ prevents assert()s to fail.
+ */
+ tfe_packetpage_ptr -= 1;
+ }
+
+ /*
+ [1] The TFE_ADDR_PP_DATA does not need to be modified here,
+ since it will be modified just before a read or store operation
+ is to be performed.
+ See [2] and [3]
+ */
+ break;
+
+ case TFE_ADDR_PP_DATA:
+ case TFE_ADDR_PP_DATA+1:
+
+ {
+ WORD ppaddress = tfe_packetpage_ptr & (MAX_PACKETPAGE_ARRAY-1);
+
+#ifdef TFE_DEBUG_STORE
+ if(g_fh) fprintf(g_fh, "before writing to PP Ptr: $%04X <= $%04X.",
+ ppaddress, GET_PP_16(ppaddress) );
+#endif
+ {
+ register WORD tmpIoAddr = ioaddress & ~1; /* word-align the address */
+ SET_PP_16(ppaddress, GET_TFE_16(tmpIoAddr));
+ }
+
+ /* perform side-effects the write may perform */
+ /* the addresses are always aligned on the whole 16-bit-word */
+ tfe_sideeffects_write_pp(ppaddress, ioaddress-TFE_ADDR_PP_DATA);
+
+#ifdef TFE_DEBUG_STORE
+ if(g_fh) fprintf(g_fh, "after writing to PP Ptr: $%04X <= $%04X.",
+ ppaddress, GET_PP_16(ppaddress) );
+#endif
+ }
+ break;
+ }
+
+ TFE_DEBUG_OUTPUT_REG();
+}
+
+
+
+static
+int set_tfe_disabled(void *v, void *param)
+{
+ /* dummy function since we don't want "disabled" to be stored on disk */
+ return 0;
+}
+
+
+static
+int set_tfe_enabled(void *v, void *param)
+{
+ if (!tfe_cannot_use) {
+
+ if (!(int)v) {
+ /* TFE should be deactived */
+ if (tfe_enabled) {
+ tfe_enabled = 0;
+ /* RGJ Commented out forAppleWin */
+ //c64export_remove(&export_res);
+ if (tfe_deactivate() < 0) {
+ return -1;
+ }
+ }
+ return 0;
+ } else {
+ if (!tfe_enabled) {
+ /* RGJ Commented out forAppleWin */
+ //if (c64export_query(&export_res) < 0)
+ // return -1;
+
+ tfe_enabled = 1;
+ if (tfe_activate() < 0) {
+ return -1;
+ }
+ /* RGJ Commented out forAppleWin */
+ //if (c64export_add(&export_res) < 0)
+ // return -1;
+
+ }
+
+ return 0;
+ }
+
+ }
+ return 0;
+}
+
+
+static
+int set_tfe_interface(void *v, void *param)
+{
+ const char *name = (const char *)v;
+
+ if (tfe_interface != NULL && name != NULL
+ && strcmp(name, tfe_interface) == 0)
+ return 0;
+
+ util_string_set(&tfe_interface, name);
+
+ if (tfe_enabled) {
+ /* ethernet is enabled, make sure that the new name is
+ taken account of
+ */
+ if (tfe_deactivate() < 0) {
+ return -1;
+ }
+ if (tfe_activate() < 0) {
+ return -1;
+ }
+
+ /* virtually reset the LAN chip */
+ if (tfe) {
+ tfe_reset();
+ }
+ }
+ return 0;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* commandline support functions */
+
+//#ifdef HAS_TRANSLATION
+//static const cmdline_option_t cmdline_options[] =
+//{
+// { "-tfe", SET_RESOURCE, 0, NULL, NULL, "ETHERNET_ACTIVE", (resource_value_t)1,
+// 0, IDCLS_ENABLE_TFE },
+// { "+tfe", SET_RESOURCE, 0, NULL, NULL, "ETHERNET_ACTIVE", (resource_value_t)0,
+// 0, IDCLS_DISABLE_TFE },
+// { NULL }
+//};
+//#else
+//static const cmdline_option_t cmdline_options[] =
+//{
+// { "-tfe", SET_RESOURCE, 0, NULL, NULL, "ETHERNET_ACTIVE", (resource_value_t)1,
+// NULL, N_("Enable the TFE (\"the final ethernet\") unit") },
+// { "+tfe", SET_RESOURCE, 0, NULL, NULL, "ETHERNET_ACTIVE", (resource_value_t)0,
+// NULL, N_("Disable the TFE (\"the final ethernet\") unit") },
+// { NULL }
+//};
+//#endif
+
+//int tfe_cmdline_options_init(void)
+//{
+// return cmdline_register_options(cmdline_options);
+//}
+
+
+/* ------------------------------------------------------------------------- */
+/* snapshot support functions */
+
+#if 0
+
+static char snap_module_name[] = "TFE1764";
+#define SNAP_MAJOR 0
+#define SNAP_MINOR 0
+
+int tfe_read_snapshot_module(struct snapshot_s *s)
+{
+ /* @SRT TODO: not yet implemented */
+ return -1;
+}
+
+int tfe_write_snapshot_module(struct snapshot_s *s)
+{
+ /* @SRT TODO: not yet implemented */
+ return -1;
+}
+
+#endif /* #if 0 */
+
+/* ------------------------------------------------------------------------- */
+/* functions for selecting and querying available NICs */
+
+int tfe_enumadapter_open(void)
+{
+ if (!tfe_arch_enumadapter_open()) {
+ tfe_cannot_use = 1;
+ return 0;
+ }
+ return 1;
+}
+
+int tfe_enumadapter(char **ppname, char **ppdescription)
+{
+ return tfe_arch_enumadapter(ppname, ppdescription);
+}
+
+int tfe_enumadapter_close(void)
+{
+ return tfe_arch_enumadapter_close();
+}
+
+
+BYTE __stdcall TfeIo (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG nCycles)
+{
+ BYTE ret = 0;
+
+ if (write) {
+ if (tfe_enabled)
+ tfe_store((WORD)(address & 0x0f), value);
+ }
+ else {
+ if (tfe_enabled)
+ ret = tfe_read((WORD)(address & 0x0f));
+ }
+
+return ret;
+
+}
+
+void get_disabled_state(int * param)
+{
+
+*param = tfe_cannot_use;
+
+}
+
+int update_tfe_interface(void *v, void *param)
+{
+ return set_tfe_interface(v,param);
+}
+
+void * get_tfe_interface(void)
+{
+ void *v;
+ v = tfe_interface;
+ return v;
+}
+
+void get_tfe_enabled(int * param)
+{
+ *param = tfe_enabled;
+}
+
+//#endif /* #ifdef HAVE_TFE */
diff --git a/AppleWin/source/Tfe/Tfe.h b/AppleWin/source/Tfe/Tfe.h
new file mode 100644
index 00000000..9a3f7761
--- /dev/null
+++ b/AppleWin/source/Tfe/Tfe.h
@@ -0,0 +1,84 @@
+/*
+ * tfe.h - TFE ("The final ethernet" emulation.
+ *
+ * Written by
+ * Spiro Trikaliotis
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+#ifndef _TFE_H
+#define _TFE_H
+
+#include "types.h"
+#include
+
+/* define this only if VICE should write each and every frame received
+ and send into the VICE log
+ WARNING: The log grows very fast!
+*/
+/** #define TFE_DEBUG_FRAMES **/
+
+struct snapshot_s;
+
+extern int tfe_enabled;
+
+extern void tfe_init(void);
+extern int tfe_resources_init(void);
+extern int tfe_cmdline_options_init(void);
+extern int update_tfe_interface(void *v, void *param);
+void get_disabled_state(int * param);
+
+extern void tfe_reset(void);
+extern void tfe_shutdown(void);
+extern BYTE REGPARM1 tfe_read(WORD addr);
+extern void REGPARM2 tfe_store(WORD addr, BYTE byte);
+extern int tfe_read_snapshot_module(struct snapshot_s *s);
+extern int tfe_write_snapshot_module(struct snapshot_s *s);
+extern BYTE __stdcall TfeIo (WORD programcounter, BYTE address, BYTE write, BYTE value, ULONG nCycles);
+
+/*
+ These functions let the UI enumerate the available interfaces.
+
+ First, tfe_enumadapter_open() is used to start enumeration.
+
+ tfe_enum_adapter is then used to gather information for each adapter present
+ on the system, where:
+
+ ppname points to a pointer which will hold the name of the interface
+ ppdescription points to a pointer which will hold the description of the interface
+
+ For each of these parameters, new memory is allocated, so it has to be
+ freed with lib_free().
+
+ tfe_enumadapter_close() must be used to stop processing.
+
+ Each function returns 1 on success, and 0 on failure.
+ tfe_enumadapter() only fails if there is no more adpater; in this case,
+ *ppname and *ppdescription are not altered.
+*/
+extern int tfe_enumadapter_open(void);
+extern int tfe_enumadapter(char **ppname, char **ppdescription);
+extern int tfe_enumadapter_close(void);
+
+
+extern FILE* g_fh; // Filehandle for log file
+
+#endif
diff --git a/AppleWin/source/Tfe/Tfearch.cpp b/AppleWin/source/Tfe/Tfearch.cpp
new file mode 100644
index 00000000..2c4cc252
--- /dev/null
+++ b/AppleWin/source/Tfe/Tfearch.cpp
@@ -0,0 +1,564 @@
+/*
+ * tfearch.c - TFE ("The final ethernet") emulation,
+ * architecture-dependant stuff
+ *
+ * Written by
+ * Spiro Trikaliotis
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+/* #define WPCAP */
+
+#include "pcap.h"
+
+#include
+#include
+#include
+#include
+
+#include "tfe.h"
+#include "tfearch.h"
+#include "tfesupp.h"
+
+
+typedef pcap_t *(*pcap_open_live_t)(const char *, int, int, int, char *);
+typedef int (*pcap_dispatch_t)(pcap_t *, int, pcap_handler, u_char *);
+typedef int (*pcap_setnonblock_t)(pcap_t *, int, char *);
+typedef int (*pcap_datalink_t)(pcap_t *);
+typedef int (*pcap_findalldevs_t)(pcap_if_t **, char *);
+typedef void (*pcap_freealldevs_t)(pcap_if_t *);
+typedef int (*pcap_sendpacket_t)(pcap_t *p, u_char *buf, int size);
+
+/** #define TFE_DEBUG_ARCH 1 **/
+/** #define TFE_DEBUG_PKTDUMP 1 **/
+
+/* #define TFE_DEBUG_FRAMES - might be defined in TFE.H! */
+
+#define TFE_DEBUG_WARN 1 /* this should not be deactivated */
+
+static pcap_open_live_t p_pcap_open_live;
+static pcap_dispatch_t p_pcap_dispatch;
+static pcap_setnonblock_t p_pcap_setnonblock;
+static pcap_findalldevs_t p_pcap_findalldevs;
+static pcap_freealldevs_t p_pcap_freealldevs;
+static pcap_sendpacket_t p_pcap_sendpacket;
+static pcap_datalink_t p_pcap_datalink;
+
+static HINSTANCE pcap_library = NULL;
+
+
+/* ------------------------------------------------------------------------- */
+/* variables needed */
+
+
+//static log_t g_fh = g_fh;
+
+
+static pcap_if_t *TfePcapNextDev = NULL;
+static pcap_if_t *TfePcapAlldevs = NULL;
+static pcap_t *TfePcapFP = NULL;
+
+static char TfePcapErrbuf[PCAP_ERRBUF_SIZE];
+
+#ifdef TFE_DEBUG_PKTDUMP
+
+static
+void debug_output( const char *text, BYTE *what, int count )
+{
+ char buffer[256];
+ char *p = buffer;
+ char *pbuffer1 = what;
+ int len1 = count;
+ int i;
+
+ sprintf(buffer, "\n%s: length = %u\n", text, len1);
+ OutputDebugString(buffer);
+ do {
+ p = buffer;
+ for (i=0; (i<8) && len1>0; len1--, i++) {
+ sprintf( p, "%02x ", (unsigned int)(unsigned char)*pbuffer1++);
+ p += 3;
+ }
+ *(p-1) = '\n'; *p = 0;
+ OutputDebugString(buffer);
+ } while (len1>0);
+}
+#endif // #ifdef TFE_DEBUG_PKTDUMP
+
+
+static
+void TfePcapFreeLibrary(void)
+{
+ if (pcap_library) {
+ if (!FreeLibrary(pcap_library)) {
+ if(g_fh) fprintf(g_fh, "FreeLibrary WPCAP.DLL failed!");
+ }
+ pcap_library = NULL;
+
+ p_pcap_open_live = NULL;
+ p_pcap_dispatch = NULL;
+ p_pcap_setnonblock = NULL;
+ p_pcap_findalldevs = NULL;
+ p_pcap_freealldevs = NULL;
+ p_pcap_sendpacket = NULL;
+ p_pcap_datalink = NULL;
+ }
+}
+
+/* since I don't like typing too much... */
+#define GET_PROC_ADDRESS_AND_TEST( _name_ ) \
+ p_##_name_ = (_name_##_t) GetProcAddress(pcap_library, #_name_ ); \
+ if (!p_##_name_ ) { \
+ if(g_fh) fprintf(g_fh, "GetProcAddress " #_name_ " failed!"); \
+ TfePcapFreeLibrary(); \
+ return FALSE; \
+ }
+
+static
+BOOL TfePcapLoadLibrary(void)
+{
+ if (!pcap_library) {
+ pcap_library = LoadLibrary("wpcap.dll");
+
+ if (!pcap_library) {
+ if(g_fh) fprintf(g_fh, "LoadLibrary WPCAP.DLL failed!" );
+ return FALSE;
+ }
+
+ GET_PROC_ADDRESS_AND_TEST(pcap_open_live);
+ GET_PROC_ADDRESS_AND_TEST(pcap_dispatch);
+ GET_PROC_ADDRESS_AND_TEST(pcap_setnonblock);
+ GET_PROC_ADDRESS_AND_TEST(pcap_findalldevs);
+ GET_PROC_ADDRESS_AND_TEST(pcap_freealldevs);
+ GET_PROC_ADDRESS_AND_TEST(pcap_sendpacket);
+ GET_PROC_ADDRESS_AND_TEST(pcap_datalink);
+ }
+
+ return TRUE;
+}
+
+#undef GET_PROC_ADDRESS_AND_TEST
+
+
+
+static
+void TfePcapCloseAdapter(void)
+{
+ if (TfePcapAlldevs) {
+ (*p_pcap_freealldevs)(TfePcapAlldevs);
+ TfePcapAlldevs = NULL;
+ }
+}
+
+/*
+ These functions let the UI enumerate the available interfaces.
+
+ First, TfeEnumAdapterOpen() is used to start enumeration.
+
+ TfeEnumAdapter is then used to gather information for each adapter present
+ on the system, where:
+
+ ppname points to a pointer which will hold the name of the interface
+ ppdescription points to a pointer which will hold the description of the interface
+
+ For each of these parameters, new memory is allocated, so it has to be
+ freed with lib_free().
+
+ TfeEnumAdapterClose() must be used to stop processing.
+
+ Each function returns 1 on success, and 0 on failure.
+ TfeEnumAdapter() only fails if there is no more adpater; in this case,
+ *ppname and *ppdescription are not altered.
+*/
+int tfe_arch_enumadapter_open(void)
+{
+ if (!TfePcapLoadLibrary()) {
+ return 0;
+ }
+
+ if ((*p_pcap_findalldevs)(&TfePcapAlldevs, TfePcapErrbuf) == -1)
+ {
+ if(g_fh) fprintf(g_fh, "ERROR in TfeEnumAdapterOpen: pcap_findalldevs: '%s'", TfePcapErrbuf);
+ return 0;
+ }
+
+ if (!TfePcapAlldevs) {
+ if(g_fh) fprintf(g_fh, "ERROR in TfeEnumAdapterOpen, finding all pcap devices - "
+ "Do we have the necessary privilege rights?");
+ return 0;
+ }
+
+ TfePcapNextDev = TfePcapAlldevs;
+
+ return 1;
+}
+
+int tfe_arch_enumadapter(char **ppname, char **ppdescription)
+{
+ if (!TfePcapNextDev)
+ return 0;
+
+ *ppname = lib_stralloc(TfePcapNextDev->name);
+ *ppdescription = lib_stralloc(TfePcapNextDev->description);
+
+ TfePcapNextDev = TfePcapNextDev->next;
+
+ return 1;
+}
+
+int tfe_arch_enumadapter_close(void)
+{
+ if (TfePcapAlldevs) {
+ (*p_pcap_freealldevs)(TfePcapAlldevs);
+ TfePcapAlldevs = NULL;
+ }
+ return 1;
+}
+
+static
+BOOL TfePcapOpenAdapter(const char *interface_name)
+{
+ pcap_if_t *TfePcapDevice = NULL;
+
+ if (!tfe_enumadapter_open()) {
+ return FALSE;
+ }
+ else {
+ /* look if we can find the specified adapter */
+ char *pname;
+ char *pdescription;
+ BOOL found = FALSE;
+
+ if (interface_name) {
+ /* we have an interface name, try it */
+ TfePcapDevice = TfePcapAlldevs;
+
+ while (tfe_enumadapter(&pname, &pdescription)) {
+ if (strcmp(pname, interface_name)==0) {
+ found = TRUE;
+ }
+ lib_free(pname);
+ lib_free(pdescription);
+ if (found) break;
+ TfePcapDevice = TfePcapNextDev;
+ }
+ }
+
+ if (!found) {
+ /* just take the first adapter */
+ TfePcapDevice = TfePcapAlldevs;
+ }
+ }
+
+ TfePcapFP = (*p_pcap_open_live)(TfePcapDevice->name, 1700, 1, 20, TfePcapErrbuf);
+ if ( TfePcapFP == NULL)
+ {
+ if(g_fh) fprintf(g_fh, "ERROR opening adapter: '%s'", TfePcapErrbuf);
+ tfe_enumadapter_close();
+ return FALSE;
+ }
+
+ if ((*p_pcap_setnonblock)(TfePcapFP, 1, TfePcapErrbuf)<0)
+ {
+ if(g_fh) fprintf(g_fh, "WARNING: Setting PCAP to non-blocking failed: '%s'", TfePcapErrbuf);
+ }
+
+ /* Check the link layer. We support only Ethernet for simplicity. */
+ if((*p_pcap_datalink)(TfePcapFP) != DLT_EN10MB)
+ {
+ if(g_fh) fprintf(g_fh, "ERROR: TFE works only on Ethernet networks.");
+ tfe_enumadapter_close();
+ return FALSE;
+ }
+
+ tfe_enumadapter_close();
+ return TRUE;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* the architecture-dependend functions */
+
+
+int tfe_arch_init(void)
+{
+ // g_fh = log_open("TFEARCH");
+
+ if (!TfePcapLoadLibrary()) {
+ return 0;
+ }
+
+ return 1;
+}
+
+void tfe_arch_pre_reset( void )
+{
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_pre_reset()." );
+#endif
+}
+
+void tfe_arch_post_reset( void )
+{
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_post_reset()." );
+#endif
+}
+
+int tfe_arch_activate(const char *interface_name)
+{
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_activate()." );
+#endif
+ if (!TfePcapOpenAdapter(interface_name)) {
+ return 0;
+ }
+ return 1;
+}
+
+void tfe_arch_deactivate( void )
+{
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_deactivate()." );
+#endif
+}
+
+void tfe_arch_set_mac( const BYTE mac[6] )
+{
+#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
+ if(g_fh) fprintf( g_fh, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
+#endif
+}
+
+void tfe_arch_set_hashfilter(const DWORD hash_mask[2])
+{
+#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
+ if(g_fh) fprintf( g_fh, "New hash filter set: %08X:%08X.",
+ hash_mask[1], hash_mask[0]);
+#endif
+}
+
+
+/*
+void tfe_arch_receive_remove_committed_frame(void)
+{
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_receive_remove_committed_frame()." );
+#endif
+}
+*/
+
+void tfe_arch_recv_ctl( int bBroadcast, /* broadcast */
+ int bIA, /* individual address (IA) */
+ int bMulticast, /* multicast if address passes the hash filter */
+ int bCorrect, /* accept correct frames */
+ int bPromiscuous, /* promiscuous mode */
+ int bIAHash /* accept if IA passes the hash filter */
+ )
+{
+#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
+ if(g_fh) {
+ fprintf( g_fh, "tfe_arch_recv_ctl() called with the following parameters:" );
+ fprintf( g_fh, "\tbBroadcast = %s", bBroadcast ? "TRUE" : "FALSE" );
+ fprintf( g_fh, "\tbIA = %s", bIA ? "TRUE" : "FALSE" );
+ fprintf( g_fh, "\tbMulticast = %s", bMulticast ? "TRUE" : "FALSE" );
+ fprintf( g_fh, "\tbCorrect = %s", bCorrect ? "TRUE" : "FALSE" );
+ fprintf( g_fh, "\tbPromiscuous = %s", bPromiscuous ? "TRUE" : "FALSE" );
+ fprintf( g_fh, "\tbIAHash = %s", bIAHash ? "TRUE" : "FALSE" );
+ }
+#endif
+}
+
+void tfe_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver )
+{
+#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
+ if(g_fh) {
+ fprintf( g_fh, "tfe_arch_line_ctl() called with the following parameters:" );
+ fprintf( g_fh, "\tbEnableTransmitter = %s", bEnableTransmitter ? "TRUE" : "FALSE" );
+ fprintf( g_fh, "\tbEnableReceiver = %s", bEnableReceiver ? "TRUE" : "FALSE" );
+ }
+#endif
+}
+
+
+typedef struct TFE_PCAP_INTERNAL_tag {
+
+ unsigned int len;
+ BYTE *buffer;
+
+} TFE_PCAP_INTERNAL;
+
+/* Callback function invoked by libpcap for every incoming packet */
+static
+void TfePcapPacketHandler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
+{
+ /* RGJ changed from void to TFE_PCAP_INTERNAL for AppleWin */
+ TFE_PCAP_INTERNAL *pinternal = (TFE_PCAP_INTERNAL *)param;
+
+ /* determine the count of bytes which has been returned,
+ * but make sure not to overrun the buffer
+ */
+ if (header->caplen < pinternal->len)
+ pinternal->len = header->caplen;
+
+ memcpy(pinternal->buffer, pkt_data, pinternal->len);
+}
+
+/* the following function receives a frame.
+
+ If there's none, it returns a -1.
+ If there is one, it returns the length of the frame in bytes.
+
+ It copies the frame to *buffer and returns the number of copied
+ bytes as return value.
+
+ At most 'len' bytes are copied.
+*/
+static
+int tfe_arch_receive_frame(TFE_PCAP_INTERNAL *pinternal)
+{
+ int ret = -1;
+
+ /* check if there is something to receive */
+ /* RGJ changed from void to u_char for AppleWin */
+ if ((*p_pcap_dispatch)(TfePcapFP, 1, TfePcapPacketHandler, (u_char *)pinternal)!=0) {
+ /* Something has been received */
+ ret = pinternal->len;
+ }
+
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_receive_frame() called, returns %d.", ret );
+#endif
+
+ return ret;
+}
+
+void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in transmit buffer */
+ int onecoll, /* ONECOLL: Terminate after just one collision */
+ int inhibit_crc, /* INHIBITCRC: Do not append CRC to the transmission */
+ int tx_pad_dis, /* TXPADDIS: Disable padding to 60 Bytes */
+ int txlength, /* Frame length */
+ BYTE *txframe /* Pointer to the frame to be transmitted */
+ )
+{
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_transmit() called, with: "
+ "force = %s, onecoll = %s, inhibit_crc=%s, tx_pad_dis=%s, txlength=%u",
+ force ? "TRUE" : "FALSE",
+ onecoll ? "TRUE" : "FALSE",
+ inhibit_crc ? "TRUE" : "FALSE",
+ tx_pad_dis ? "TRUE" : "FALSE",
+ txlength
+ );
+#endif
+
+#ifdef TFE_DEBUG_PKTDUMP
+ debug_output( "Transmit frame: ", txframe, txlength);
+#endif // #ifdef TFE_DEBUG_PKTDUMP
+
+ if ((*p_pcap_sendpacket)(TfePcapFP, txframe, txlength) == -1) {
+ if(g_fh) fprintf(g_fh, "WARNING! Could not send packet!");
+ }
+}
+
+/*
+ tfe_arch_receive()
+
+ This function checks if there was a frame received.
+ If so, it returns 1, else 0.
+
+ If there was no frame, none of the parameters is changed!
+
+ If there was a frame, the following actions are done:
+
+ - at maximum *plen byte are transferred into the buffer given by pbuffer
+ - *plen gets the length of the received frame, EVEN if this is more
+ than has been copied to pbuffer!
+ - if the dest. address was accepted by the hash filter, *phashed is set, else
+ cleared.
+ - if the dest. address was accepted by the hash filter, *phash_index is
+ set to the number of the rule leading to the acceptance
+ - if the receive was ok (good CRC and valid length), *prx_ok is set,
+ else cleared.
+ - if the dest. address was accepted because it's exactly our MAC address
+ (set by tfe_arch_set_mac()), *pcorrect_mac is set, else cleared.
+ - if the dest. address was accepted since it was a broadcast address,
+ *pbroadcast is set, else cleared.
+ - if the received frame had a crc error, *pcrc_error is set, else cleared
+*/
+int tfe_arch_receive(BYTE *pbuffer , /* where to store a frame */
+ int *plen, /* IN: maximum length of frame to copy;
+ OUT: length of received frame
+ OUT can be bigger than IN if received frame was
+ longer than supplied buffer */
+ int *phashed, /* set if the dest. address is accepted by the hash filter */
+ int *phash_index, /* hash table index if hashed == TRUE */
+ int *prx_ok, /* set if good CRC and valid length */
+ int *pcorrect_mac, /* set if dest. address is exactly our IA */
+ int *pbroadcast, /* set if dest. address is a broadcast address */
+ int *pcrc_error /* set if received frame had a CRC error */
+ )
+{
+ int len;
+
+ TFE_PCAP_INTERNAL internal = { *plen, pbuffer };
+
+
+#ifdef TFE_DEBUG_ARCH
+ if(g_fh) fprintf( g_fh, "tfe_arch_receive() called, with *plen=%u.", *plen );
+#endif
+
+ assert((*plen&1)==0);
+
+ len = tfe_arch_receive_frame(&internal);
+
+ if (len!=-1) {
+
+#ifdef TFE_DEBUG_PKTDUMP
+ debug_output( "Received frame: ", internal.buffer, internal.len );
+#endif // #ifdef TFE_DEBUG_PKTDUMP
+
+ if (len&1)
+ ++len;
+
+ *plen = len;
+
+ /* we don't decide if this frame fits the needs;
+ * by setting all zero, we let tfe.c do the work
+ * for us
+ */
+ *phashed =
+ *phash_index =
+ *pbroadcast =
+ *pcorrect_mac =
+ *pcrc_error = 0;
+
+ /* this frame has been received correctly */
+ *prx_ok = 1;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//#endif /* #ifdef HAVE_TFE */
diff --git a/AppleWin/source/Tfe/Tfearch.h b/AppleWin/source/Tfe/Tfearch.h
new file mode 100644
index 00000000..37e3a111
--- /dev/null
+++ b/AppleWin/source/Tfe/Tfearch.h
@@ -0,0 +1,91 @@
+/*
+ * tfearch.h - TFE ("The final ethernet") emulation.
+ * architecture-dependant stuff
+ *
+ * Written by
+ * Spiro Trikaliotis
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+#ifndef _TFEARCH_H
+#define _TFEARCH_H
+
+#include "types.h"
+
+extern int tfe_arch_init(void);
+extern void tfe_arch_pre_reset(void);
+extern void tfe_arch_post_reset(void);
+extern int tfe_arch_activate(const char *interface_name);
+extern void tfe_arch_deactivate(void);
+extern void tfe_arch_set_mac(const BYTE mac[6]);
+extern void tfe_arch_set_hashfilter(const DWORD hash_mask[2]);
+
+extern
+void tfe_arch_recv_ctl( int bBroadcast, /* broadcast */
+ int bIA, /* individual address (IA) */
+ int bMulticast, /* multicast if address passes the hash filter */
+ int bCorrect, /* accept correct frames */
+ int bPromiscuous, /* promiscuous mode */
+ int bIAHash /* accept if IA passes the hash filter */
+ );
+
+extern
+void tfe_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver);
+
+extern
+void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in transmit buffer */
+ int onecoll, /* ONECOLL: Terminate after just one collision */
+ int inhibit_crc, /* INHIBITCRC: Do not append CRC to the transmission */
+ int tx_pad_dis, /* TXPADDIS: Disable padding to 60 Bytes */
+ int txlength, /* Frame length */
+ BYTE *txframe /* Pointer to the frame to be transmitted */
+ );
+
+extern
+int tfe_arch_receive(BYTE *pbuffer , /* where to store a frame */
+ int *plen, /* IN: maximum length of frame to copy;
+ OUT: length of received frame
+ OUT can be bigger than IN if received frame was
+ longer than supplied buffer */
+ int *phashed, /* set if the dest. address is accepted by the hash filter */
+ int *phash_index, /* hash table index if hashed == TRUE */
+ int *prx_ok, /* set if good CRC and valid length */
+ int *pcorrect_mac, /* set if dest. address is exactly our IA */
+ int *pbroadcast, /* set if dest. address is a broadcast address */
+ int *pcrc_error /* set if received frame had a CRC error */
+ );
+
+/*
+ This is a helper for tfe_receive() to determine if the received frame should be accepted
+ according to the settings.
+
+ This function is even allowed to be called in tfearch.c from tfe_arch_receive() if
+ necessary, which is the reason why its prototype is included here in tfearch.h.
+*/
+extern
+int tfe_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index,
+ int *pcorrect_mac, int *pbroadcast, int *pmulticast);
+
+extern int tfe_arch_enumadapter_open(void);
+extern int tfe_arch_enumadapter(char **ppname, char **ppdescription);
+extern int tfe_arch_enumadapter_close(void);
+
+#endif
diff --git a/AppleWin/source/Tfe/Tfesupp.cpp b/AppleWin/source/Tfe/Tfesupp.cpp
new file mode 100644
index 00000000..9b2124f2
--- /dev/null
+++ b/AppleWin/source/Tfe/Tfesupp.cpp
@@ -0,0 +1,188 @@
+/*
+ * This file is a consolidation of functions required for tfe
+ * emulation taken from the following files
+ *
+ * lib.c - Library functions.
+ * util.c - Miscellaneous utility functions.
+ * crc32.c
+ *
+ * Written by
+ * Andreas Boose
+ * Ettore Perazzoli
+ * Andreas Matthies
+ * Tibor Biczo
+ * Spiro Trikaliotis *
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "tfesupp.h"
+
+
+// Lib Stuff
+/* #define LIB_DEBUG*/
+
+
+#ifdef LIB_DEBUG
+#define LIB_DEBUG_SIZE 0x10000
+#define LIB_DEBUG_GUARD 0x1000
+#endif
+
+#define CRC32_POLY 0xedb88320
+static unsigned long crc32_table[256];
+static int crc32_is_initialized = 0;
+
+void lib_free(void *ptr)
+{
+#ifdef LIB_DEBUG
+ lib_debug_free(ptr, 1, 1);
+#endif
+
+#ifdef LIB_DEBUG
+ lib_debug_libc_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+void *lib_malloc(size_t size)
+{
+#ifdef LIB_DEBUG
+ void *ptr = lib_debug_libc_malloc(size);
+#else
+ void *ptr = malloc(size);
+#endif
+
+#ifndef __OS2__
+ if (ptr == NULL && size > 0)
+ exit(-1);
+#endif
+#ifdef LIB_DEBUG
+ lib_debug_alloc(ptr, size, 3);
+#endif
+
+ return ptr;
+}
+
+/*-----------------------------------------------------------------------*/
+
+/* Malloc enough space for `str', copy `str' into it and return its
+ address. */
+char *lib_stralloc(const char *str)
+{
+ size_t size;
+ char *ptr;
+
+ if (str == NULL)
+ exit(-1);
+
+ size = strlen(str) + 1;
+ ptr = (char *)lib_malloc(size);
+
+ memcpy(ptr, str, size);
+ return ptr;
+}
+
+
+
+/* Like realloc, but abort if not enough memory is available. */
+void *lib_realloc(void *ptr, size_t size)
+{
+#ifdef LIB_DEBUG
+ void *new_ptr = lib_debug_libc_realloc(ptr, size);
+#else
+ void *new_ptr = realloc(ptr, size);
+#endif
+
+#ifndef __OS2__
+ if (new_ptr == NULL)
+ exit(-1);
+#endif
+#ifdef LIB_DEBUG
+ lib_debug_free(ptr, 1, 0);
+ lib_debug_alloc(new_ptr, size, 1);
+#endif
+
+ return new_ptr;
+}
+
+// Util Stuff
+
+/* Set a new value to the dynamically allocated string *str.
+ Returns `-1' if nothing has to be done. */
+int util_string_set(char **str, const char *new_value)
+{
+ if (*str == NULL) {
+ if (new_value != NULL)
+ *str = lib_stralloc(new_value);
+ } else {
+ if (new_value == NULL) {
+ lib_free(*str);
+ *str = NULL;
+ } else {
+ /* Skip copy if src and dest are already the same. */
+ if (strcmp(*str, new_value) == 0)
+ return -1;
+
+ *str = (char *)lib_realloc(*str, strlen(new_value) + 1);
+ strcpy(*str, new_value);
+ }
+ }
+ return 0;
+}
+
+
+// crc32 Stuff
+
+unsigned long crc32_buf(const char *buffer, unsigned int len)
+{
+ int i, j;
+ unsigned long crc, c;
+ const char *p;
+
+ if (!crc32_is_initialized) {
+ for (i = 0; i < 256; i++) {
+ c = (unsigned long) i;
+ for (j = 0; j < 8; j++)
+ c = c & 1 ? CRC32_POLY ^ (c >> 1) : c >> 1;
+ crc32_table[i] = c;
+ }
+ crc32_is_initialized = 1;
+ }
+
+ crc = 0xffffffff;
+ for (p = buffer; len > 0; ++p, --len)
+ crc = (crc >> 8) ^ crc32_table[(crc ^ *p) & 0xff];
+
+ return ~crc;
+}
+
diff --git a/AppleWin/source/Tfe/Tfesupp.h b/AppleWin/source/Tfe/Tfesupp.h
new file mode 100644
index 00000000..ef6928e6
--- /dev/null
+++ b/AppleWin/source/Tfe/Tfesupp.h
@@ -0,0 +1,53 @@
+/*
+ * This file is a consolidation of functions required for tfe
+ * emulation taken from the following files
+ *
+ * lib.h - Library functions.
+ * util.h - Miscellaneous utility functions.
+ * crc32.h
+ *
+ * Written by
+ * Andreas Boose
+ * Ettore Perazzoli
+ * Manfred Spraul
+ * Andreas Matthies
+ * Tibor Biczo
+ * Spiro Trikaliotis *
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+
+
+#ifndef _TFESUPP_H
+#define _TFESUPP_H
+
+extern FILE* g_fh; // Filehandle for log file
+
+extern void *lib_malloc(size_t size);
+extern void *lib_realloc(void *p, size_t size);
+extern void lib_free(void *ptr);
+extern char *lib_stralloc(const char *str);
+
+extern int util_string_set(char **str, const char *new_value);
+
+extern unsigned long crc32_buf(const char *buffer, unsigned int len);
+
+#endif
diff --git a/AppleWin/source/Tfe/Types.h b/AppleWin/source/Tfe/Types.h
new file mode 100644
index 00000000..db56ca7e
--- /dev/null
+++ b/AppleWin/source/Tfe/Types.h
@@ -0,0 +1,73 @@
+/*
+ * types.h - Type definitions for VICE.
+ *
+ * Written by
+ * Ettore Perazzoli
+ * André Fachat
+ * Teemu Rantanen
+ * Andreas Boose
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+#ifndef _TYPES_H
+#define _TYPES_H
+
+#ifndef BYTE
+#define BYTE unsigned char
+#endif
+
+#ifndef WORD
+#define WORD unsigned short
+#endif
+
+#ifndef DWORD
+ //#ifdef DWORD_IS_LONG
+ #define DWORD unsigned long
+ //#else
+ //#define DWORD unsigned int
+ //#endif
+#endif
+
+/* RGJ added for AppleWin */
+#ifndef ULONG
+typedef unsigned long ULONG;
+#endif
+
+typedef signed char SIGNED_CHAR;
+typedef signed short SWORD;
+typedef signed int SDWORD;
+
+typedef DWORD CLOCK;
+/* Maximum value of a CLOCK. */
+#define CLOCK_MAX (~((CLOCK)0))
+
+#if defined(__GNUC__) && defined(__i386__) && !defined(NO_REGPARM)
+#define REGPARM1 __attribute__((regparm(1)))
+#define REGPARM2 __attribute__((regparm(2)))
+#define REGPARM3 __attribute__((regparm(3)))
+#else
+#define REGPARM1
+#define REGPARM2
+#define REGPARM3
+#endif
+
+#endif
+
diff --git a/AppleWin/source/Tfe/Uilib.cpp b/AppleWin/source/Tfe/Uilib.cpp
new file mode 100644
index 00000000..1cb85b28
--- /dev/null
+++ b/AppleWin/source/Tfe/Uilib.cpp
@@ -0,0 +1,128 @@
+/*
+ * uilib.c - Common UI elements for the Windows user interface.
+ *
+ * Written by
+ * Ettore Perazzoli
+ * Andreas Boose
+ * Manfred Spraul
+ * Andreas Matthies
+ * Tibor Biczo
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "uilib.h"
+
+
+
+
+/* Mingw & pre VC 6 headers doesn't have this definition */
+#ifndef OFN_ENABLESIZING
+#define OFN_ENABLESIZING 0x00800000
+#endif
+
+void uilib_get_general_window_extents(HWND hwnd, int *xsize, int *ysize)
+{
+ HDC hdc;
+ HFONT hFont;
+ HFONT hOldFont;
+ int strlen;
+ char *buffer;
+ SIZE size;
+
+ hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
+ strlen = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
+ /* RGJ added cast for AppleWin */
+ buffer = (char *) malloc(strlen + 1);
+ GetWindowText(hwnd, buffer, strlen + 1);
+
+ hdc = GetDC(hwnd);
+ hOldFont = (HFONT)SelectObject(hdc, hFont);
+
+ GetTextExtentPoint32(hdc, buffer, strlen, &size);
+
+ free(buffer);
+
+ SelectObject(hdc, hOldFont);
+ ReleaseDC(hwnd, hdc);
+
+ *xsize = size.cx;
+ *ysize = size.cy;
+}
+
+void uilib_get_group_extent(HWND hwnd, uilib_dialog_group *group, int *xsize, int *ysize)
+{
+HWND element;
+int x;
+int y;
+
+ if (xsize && ysize) {
+ *xsize = 0;
+ *ysize = 0;
+ while (group->idc) {
+ element = GetDlgItem(hwnd, group->idc);
+ uilib_get_general_window_extents(element, &x, &y);
+ if (group->element_type == 1) x += 20;
+ if (*xsize < x) *xsize = x;
+ *ysize += y;
+ group++;
+ }
+ }
+}
+
+
+void uilib_move_group(HWND hwnd, uilib_dialog_group *group, int xpos)
+{
+HWND element;
+RECT element_rect;
+
+ while (group->idc) {
+ element = GetDlgItem(hwnd, group->idc);
+ GetClientRect(element, &element_rect);
+ MapWindowPoints(element, hwnd, (POINT*)&element_rect, 2);
+ MoveWindow(element, xpos, element_rect.top, element_rect.right - element_rect.left, element_rect.bottom - element_rect.top, TRUE);
+ group++;
+ }
+}
+
+void uilib_adjust_group_width(HWND hwnd, uilib_dialog_group *group)
+{
+HWND element;
+RECT element_rect;
+int xsize;
+int ysize;
+
+ while (group->idc) {
+ element = GetDlgItem(hwnd, group->idc);
+ GetClientRect(element, &element_rect);
+ MapWindowPoints(element, hwnd, (POINT*)&element_rect, 2);
+ uilib_get_general_window_extents(element, &xsize, &ysize);
+ if (group->element_type == 1) xsize += 20;
+ MoveWindow(element, element_rect.left, element_rect.top, xsize, element_rect.bottom - element_rect.top, TRUE);
+ group++;
+ }
+}
diff --git a/AppleWin/source/Tfe/Uilib.h b/AppleWin/source/Tfe/Uilib.h
new file mode 100644
index 00000000..1dea19ae
--- /dev/null
+++ b/AppleWin/source/Tfe/Uilib.h
@@ -0,0 +1,53 @@
+/*
+ * uilib.h - Common UI elements for the Windows user interface.
+ *
+ * Written by
+ * Ettore Perazzoli
+ * Andreas Boose
+ * Manfred Spraul
+ *
+ * This file is part of VICE, the Versatile Commodore Emulator.
+ * See README for copyright notice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA.
+ *
+ */
+
+#ifndef _UILIB_H
+#define _UILIB_H
+
+#include
+#include
+
+extern void uilib_get_general_window_extents(HWND hwnd, int *xsize, int *ysize);
+
+typedef struct {
+ unsigned int idc;
+ int element_type;
+} uilib_dialog_group;
+
+extern void uilib_get_group_extent(HWND hwnd, uilib_dialog_group *group, int *xsize, int *ysize);
+extern void uilib_move_group(HWND hwnd, uilib_dialog_group *group, int xpos);
+extern void uilib_adjust_group_width(HWND hwnd, uilib_dialog_group *group);
+
+typedef struct {
+ unsigned int idc;
+ unsigned int ids;
+ int element_type;
+} uilib_localize_dialog_param;
+
+#endif
+