diff --git a/src/86box.h b/src/86box.h index e64507a17..770ecd6b6 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.8 2017/10/27 + * Version: @(#)86box.h 1.0.9 2017/10/28 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -95,6 +95,7 @@ extern wchar_t exe_path[1024]; /* path (dir) of executable */ extern wchar_t cfg_path[1024]; /* path (dir) of user data */ extern int scrnsz_x, /* current screen size, X */ scrnsz_y; /* current screen size, Y */ +extern int config_changed; /* configuration has changed */ /* Function prototypes. */ diff --git a/src/bugger.c b/src/bugger.c index 5d6f77ce0..6a45a5c13 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -44,7 +44,7 @@ * configuration register (CTRL_SPCFG bit set) but have to * remember that stuff first... * - * Version: @(#)bugger.c 1.0.8 2017/10/16 + * Version: @(#)bugger.c 1.0.9 2017/10/28 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -54,8 +54,9 @@ #include #include #include "86box.h" -#include "ibm.h" #include "io.h" +#include "device.h" +#include "plat.h" #include "ui.h" #include "bugger.h" @@ -307,23 +308,36 @@ bug_read(uint16_t port, void *priv) /* Initialize the ISA BusBugger emulator. */ -void -bugger_init(void) +static void * +bug_init(device_t *info) { - pclog("ISA Bus (de)Bugger, I/O=%04x\n", BUGGER_ADDR); + pclog("%s, I/O=%04x\n", info->name, BUGGER_ADDR); /* Initialize local registers. */ bug_reset(); io_sethandler(BUGGER_ADDR, BUGGER_ADDRLEN, bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); + + /* Just so its not NULL. */ + return(info); } /* Remove the ISA BusBugger emulator from the system. */ -void -bugger_remove(void) +static void +bug_close(UNUSED(void *priv)) { io_removehandler(BUGGER_ADDR, BUGGER_ADDRLEN, bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); } + + +device_t bugger_device = { + "ISA/PCI Bus Bugger", + DEVICE_ISA | DEVICE_AT, + 0, + bug_init, bug_close, NULL, + NULL, NULL, NULL, NULL, + NULL +}; diff --git a/src/bugger.h b/src/bugger.h index a4135648c..0726d8b01 100644 --- a/src/bugger.h +++ b/src/bugger.h @@ -15,7 +15,7 @@ * * Definitions for the BUGGER card. * - * Version: @(#)bugger.h 1.0.4 2017/10/15 + * Version: @(#)bugger.h 1.0.5 2017/10/28 * * Author: Fred N. van Kempen, * @@ -34,9 +34,11 @@ extern "C" { #endif +/* Global variables. */ +extern device_t bugger_device; + + /* Functions. */ -extern void bugger_init(void); -extern void bugger_remove(void); #ifdef __cplusplus } diff --git a/src/cdrom/cdrom_dosbox.cpp b/src/cdrom/cdrom_dosbox.cpp index de3c146a4..3d34df9c2 100644 --- a/src/cdrom/cdrom_dosbox.cpp +++ b/src/cdrom/cdrom_dosbox.cpp @@ -20,7 +20,7 @@ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE -#ifdef WIN32 +#ifdef _WIN32 //FIXME: should not be needed. */ # define _GNU_SOURCE #endif @@ -40,10 +40,10 @@ #include "../plat.h" #include "cdrom_dosbox.h" -#if !defined(WIN32) -#include +#ifndef _WIN32 +# include #else -#include +# include #endif using namespace std; @@ -287,7 +287,7 @@ bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, uint64_t sectorSize, boo (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); } -#if defined(WIN32) +#ifdef _WIN32 static string dirname(char * file) { char * sep = strrchr(file, '\\'); if (sep == NULL) @@ -506,7 +506,7 @@ bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) filename = tmpstr; return true; } -#if defined (WIN32) || defined(OS2) +#if defined (_WIN32) || defined(OS2) //Nothing #else //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) diff --git a/src/config.c b/src/config.c index f02d3a133..ccb9eb07c 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.27 2017/10/25 + * Version: @(#)config.c 1.0.29 2017/10/28 * * Authors: Sarah Walker, * Miran Grca, @@ -242,7 +242,7 @@ config_read(wchar_t *fn) int c, d; FILE *f; -#if defined(ANSI_CFG) || !defined(WIN32) +#if defined(ANSI_CFG) || !defined(_WIN32) f = plat_fopen(fn, L"rt"); #else f = plat_fopen(fn, L"rt, ccs=UNICODE"); @@ -350,7 +350,7 @@ config_write(wchar_t *fn) FILE *f; int fl = 0; -#if defined(ANSI_CFG) || !defined(WIN32) +#if defined(ANSI_CFG) || !defined(_WIN32) f = plat_fopen(fn, L"wt"); #else f = plat_fopen(fn, L"wt, ccs=UNICODE"); @@ -395,7 +395,7 @@ config_write(wchar_t *fn) static void config_new(void) { -#if defined(ANSI_CFG) || !defined(WIN32) +#if defined(ANSI_CFG) || !defined(_WIN32) FILE *f = _wfopen(config_file, L"wt"); #else FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); @@ -1157,6 +1157,9 @@ config_load(wchar_t *fn) load_hard_disks(); /* Hard disks */ load_removable_devices(); /* Removable devices */ + /* Mark the configuration as changed. */ + config_changed = 1; + pclog("Config loaded.\n\n"); } diff --git a/src/cpu/codegen.h b/src/cpu/codegen.h index 64a944d66..1c760d696 100644 --- a/src/cpu/codegen.h +++ b/src/cpu/codegen.h @@ -6,7 +6,7 @@ #ifdef __amd64__ #include "codegen_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 #include "codegen_x86.h" #else #error Dynamic recompiler not implemented on your platform diff --git a/src/cpu/codegen_ops.c b/src/cpu/codegen_ops.c index b101222a6..60ceaa42e 100644 --- a/src/cpu/codegen_ops.c +++ b/src/cpu/codegen_ops.c @@ -16,7 +16,7 @@ #ifdef __amd64__ #include "codegen_ops_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 #include "codegen_ops_x86.h" #endif diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index a3932e55a..72b527c28 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -1,4 +1,4 @@ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 #include #include @@ -24,7 +24,7 @@ #include #include #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 +#if defined _WIN32 #include #endif @@ -1135,7 +1135,7 @@ void codegen_init() long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 +#ifdef _WIN32 codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 5af874826..08c0b44bc 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -8,16 +8,16 @@ * * x87 FPU instructions core. * - * Version: @(#)x87_ops.h 1.0.0 2017/05/30 + * Version: @(#)x87_ops.h 1.0.1 2017/10/28 * * Author: Sarah Walker, * leilei, * Miran Grca, + * * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 leilei. - * Copyright 2016-2017 Miran Grca. + * Copyright 2016,2017 Miran Grca. */ - #include #include @@ -244,7 +244,7 @@ static __inline void x87_stmmx(MMX_REG r) static __inline uint16_t x87_compare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 uint32_t out; if (!is386) @@ -316,7 +316,7 @@ static __inline uint16_t x87_compare(double a, double b) static __inline uint16_t x87_ucompare(double a, double b) { -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 +#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32 uint32_t out; /* Memory barrier, to force GCC to write to the input parameters diff --git a/src/keyboard.c b/src/keyboard.c index 7d68edb93..a6ad9d6dc 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -8,7 +8,7 @@ * * Host to guest keyboard interface and keyboard scan code sets. * - * Version: @(#)keyboard.c 1.0.6 2017/10/24 + * Version: @(#)keyboard.c 1.0.7 2017/10/28 * * Authors: Sarah Walker, * Miran Grca, @@ -580,11 +580,11 @@ keyboard_isfsexit(void) int keyboard_ismsexit(void) { -#ifdef WIN32 +#ifdef _WIN32 /* Windows: F8+F12 */ return( recv_key[0x42] && recv_key[0x58] ); #else - /* Linux: CTRL+END */ + /* WxWidgets cannot do two regular keys.. CTRL+END */ return( (recv_key[0x1D] || recv_key[0x9D]) && recv_key[0xCF] ); #endif } diff --git a/src/lzf/lzfP.h b/src/lzf/lzfP.h index 1fae96a32..11c965ca3 100644 --- a/src/lzf/lzfP.h +++ b/src/lzf/lzfP.h @@ -141,7 +141,7 @@ using namespace std; #endif #ifndef LZF_USE_OFFSETS -# if defined (WIN32) +# if defined(_WIN32) # define LZF_USE_OFFSETS defined(_M_X64) # else # if __cplusplus > 199711L diff --git a/src/lzf/lzf_c.c b/src/lzf/lzf_c.c index 120b4a5aa..8ba4d0b84 100644 --- a/src/lzf/lzf_c.c +++ b/src/lzf/lzf_c.c @@ -121,7 +121,7 @@ lzf_compress (const void *const in_data, unsigned int in_len, * and fails to support both assumptions is windows 64 bit, we make a * special workaround for it. */ -#if defined (WIN32) && defined (_M_X64) +#if defined(_WIN32) && defined(_M_X64) uint64_t off; /* workaround for missing POSIX compliance */ #else unsigned long off; diff --git a/src/machine/machine_at.c b/src/machine/machine_at.c index 71cde9e1b..c6153d9d3 100644 --- a/src/machine/machine_at.c +++ b/src/machine/machine_at.c @@ -10,7 +10,6 @@ #include "../mem.h" #include "../device.h" #include "../nvr.h" -#include "../bugger.h" #include "../game/gameport.h" #include "../keyboard_at.h" #include "../lpt.h" @@ -37,9 +36,6 @@ machine_at_init(machine_t *model) if (joystick_type != 7) device_add(&gameport_device); - - if (bugger_enabled) - bugger_init(); } diff --git a/src/machine/machine_xt.c b/src/machine/machine_xt.c index 2954390e1..c63c17cfc 100644 --- a/src/machine/machine_xt.c +++ b/src/machine/machine_xt.c @@ -8,7 +8,6 @@ #include "../pit.h" #include "../mem.h" #include "../device.h" -#include "../bugger.h" #include "../game/gameport.h" #include "../keyboard_xt.h" #include "machine.h" @@ -17,15 +16,12 @@ void machine_xt_init(machine_t *model) { - machine_common_init(model); + machine_common_init(model); - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - keyboard_xt_init(); - nmi_init(); - if (joystick_type != 7) - device_add(&gameport_device); - - if (bugger_enabled) - bugger_init(); + keyboard_xt_init(); + nmi_init(); + if (joystick_type != 7) + device_add(&gameport_device); } diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index c929171b3..f9149d941 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -10,7 +10,7 @@ * * NOTE: The file will also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.20 2017/10/19 + * Version: @(#)net_ne2000.c 1.0.21 2017/10/28 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -1673,8 +1673,6 @@ mcast_index(const void *dst) static void nic_tx(nic_t *dev, uint32_t val) { - ui_sb_update_icon(SB_NETWORK, 1); - dev->CR.tx_packet = 0; dev->TSR.tx_ok = 1; dev->ISR.pkt_tx = 1; @@ -1683,8 +1681,6 @@ nic_tx(nic_t *dev, uint32_t val) if (dev->IMR.tx_inte) nic_interrupt(dev, 1); dev->tx_timer_active = 0; - - ui_sb_update_icon(SB_NETWORK, 0); } @@ -1705,6 +1701,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) int idx, nextpage; int endbytes; + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 1); if (io_len != 60) @@ -1736,6 +1733,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) ) { nelog(1, "%s: no space\n", dev->name); + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 0); return; } @@ -1743,6 +1741,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { nelog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 0); return; } @@ -1765,6 +1764,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (! dev->RCR.broadcast) { nelog(2, "%s: RX BC disabled\n", dev->name); + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 0); return; } @@ -1778,6 +1778,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) nelog(2, "%s: RX MC disabled\n", dev->name); #endif + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 0); return; } @@ -1787,6 +1788,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) { nelog(2, "%s: RX MC not listed\n", dev->name); + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 0); return; } @@ -1833,6 +1835,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (dev->IMR.rx_inte) nic_interrupt(dev, 1); + //FIXME: move to upper layer ui_sb_update_icon(SB_NETWORK, 0); } @@ -2030,29 +2033,12 @@ nic_init(device_t *info) /* Reset the board. */ nic_reset(dev); - if (network_attach(dev, dev->physaddr, nic_rx) < 0) { -#if 0 - msgbox_error_wstr(ghwnd, L"Unable to init platform network"); -#endif - nelog(0, "%s: unable to init platform network type %d\n", - dev->name, network_type); -#if 0 - /* - * To avoid crashes, we ignore the fact that even though - * there is no active platform support, we just continue - * initializing. If we return an error here, the device - * handling code will throw a fatal error... --FvK - */ - free(dev); - return(NULL); -#endif - } + /* Attach ourselves to the network module. */ + network_attach(dev, dev->physaddr, nic_rx); nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); - ui_sb_update_icon(SB_NETWORK, 0); - return(dev); } diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 2ec78ae3e..af054db22 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -29,18 +29,11 @@ #include "network.h" -static volatile - void *pcap_handle; /* handle to WinPcap DLL */ -static volatile - pcap_t *pcap; /* handle to WinPcap library */ -static volatile - thread_t *poll_tid; -static volatile - NETRXCB poll_rx; /* network RX function to call */ -static volatile - void *poll_arg; /* network RX function arg */ -static volatile - event_t *thread_started; +static volatile void *pcap_handle; /* handle to WinPcap DLL */ +static volatile pcap_t *pcap; /* handle to WinPcap library */ +static volatile thread_t *poll_tid; +static netcard_t *poll_card; /* netcard linked to us */ +static event_t *poll_state; /* Pointers to the real functions. */ @@ -73,26 +66,28 @@ static void poll_thread(void *arg) { uint8_t *mac = (uint8_t *)arg; - const uint8_t *data = NULL; + uint8_t *data = NULL; struct pcap_pkthdr h; uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; event_t *evt; - pclog("PCAP: polling thread started, arg %08lx\n", arg); - thread_set_event((event_t *)thread_started); + pclog("PCAP: polling started.\n"); + thread_set_event(poll_state); /* Create a waitable event. */ evt = thread_create_event(); /* As long as the channel is open.. */ while (pcap != NULL) { - network_mutex_wait(1); + /* Request ownership of the device. */ + network_wait(1); - network_wait_for_poll(); + /* Wait for a poll request. */ + network_poll(); /* Wait for the next packet to arrive. */ - data = f_pcap_next((pcap_t *)pcap, &h); + data = (uint8_t *)f_pcap_next((pcap_t *)pcap, &h); if (data != NULL) { /* Received MAC. */ mac_cmp32[0] = *(uint32_t *)(data+6); @@ -103,8 +98,8 @@ poll_thread(void *arg) mac_cmp16[1] = *(uint16_t *)(mac+4); if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { - if (poll_rx != NULL) - poll_rx((void *)poll_arg, (uint8_t *)data, h.caplen); + + poll_card->rx(poll_card->priv, data, h.caplen); } else { /* Mark as invalid packet. */ data = NULL; @@ -115,18 +110,27 @@ poll_thread(void *arg) if (data == NULL) thread_wait_event(evt, 10); - network_mutex_wait(0); + /* Release ownership of the device. */ + network_wait(0); } + /* No longer needed. */ thread_destroy_event(evt); pclog("PCAP: polling stopped.\n"); + thread_set_event(poll_state); } -/* Initialize the (Win)Pcap module for use. */ +/* + * Prepare the (Win)Pcap module for use. + * + * This is called only once, during application init, + * to check for availability of PCAP, and to retrieve + * a list of (usable) intefaces for it. + */ int -network_pcap_init(netdev_t *list) +net_pcap_prepare(netdev_t *list) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *devlist, *dev; @@ -136,7 +140,7 @@ network_pcap_init(netdev_t *list) pcap = NULL; /* Try loading the DLL. */ -#ifdef WIN32 +#ifdef _WIN32 pcap_handle = dynld_module("wpcap.dll", pcap_imports); #else pcap_handle = dynld_module("libpcap.so", pcap_imports); @@ -165,84 +169,49 @@ network_pcap_init(netdev_t *list) } -/* Initialize the (Win)Pcap module for use. */ -// FIXME: this will be deleted. --FvK -void -network_pcap_reset(void) +/* + * Initialize (Win)Pcap for use. + * + * This is called on every 'cycle' of the emulator, + * if and as long the NetworkType is set to PCAP, + * and also as long as we have a NetCard defined. + */ +int +net_pcap_init(void) { - /* Try loading the DLL. */ -#ifdef WIN32 + char errbuf[PCAP_ERRBUF_SIZE]; + char *str; + + /* Did we already load the library? */ + if (pcap_handle == NULL) return(-1); +#if 0 + // no, we don't.. + /* Load the DLL if needed. We already know it exists. */ +#ifdef _WIN32 pcap_handle = dynld_module("wpcap.dll", pcap_imports); #else pcap_handle = dynld_module("libpcap.so", pcap_imports); #endif -} - - -/* Initialize WinPcap for us. */ -int -network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) -{ - char temp[PCAP_ERRBUF_SIZE]; - char filter_exp[255]; - struct bpf_program fp; - char *dev; - - /* Did we already load the DLL? */ if (pcap_handle == NULL) return(-1); +#endif + + /* Get the PCAP library name and version. */ + strcpy(errbuf, f_pcap_lib_version()); + str = strchr(errbuf, '('); + if (str != NULL) *(str-1) = '\0'; + pclog("PCAP: initializing, %s\n", errbuf); /* Get the value of our capture interface. */ - dev = network_pcap; - if ((dev == NULL) || (dev[0] == '\0') || !strcmp(dev, "none")) { - pclog(" No PCap interface configured!\n"); - return(-1); - } - pclog(" Network interface: '%s'\n", dev); - - strcpy(temp, f_pcap_lib_version()); - dev = strchr(temp, '('); - if (dev != NULL) *(dev-1) = '\0'; - pclog("PCAP: initializing, %s\n", temp); - - pcap = f_pcap_open_live(network_pcap, /* interface name */ - 1518, /* maximum packet size */ - 1, /* promiscuous mode? */ - 10, /* timeout in msec */ - temp); /* error buffer */ - if (pcap == NULL) { - pclog(" Unable to open device: %s!\n", network_pcap); + if ((network_pcap == NULL) || + (network_pcap[0] == '\0') || + !strcmp(network_pcap, "none")) { + pclog("PCAP: no interface configured!\n"); return(-1); } - /* Create a MAC address based packet filter. */ - pclog(" Installing packet filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - sprintf(filter_exp, - "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - if (f_pcap_compile((pcap_t *) pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { - if (f_pcap_setfilter((pcap_t *)pcap, &fp) != 0) { - pclog(" Error installing filter (%s) !\n", filter_exp); - f_pcap_close((pcap_t *)pcap); - return(-1); - } - } else { - pclog(" Could not compile filter (%s) !\n", filter_exp); - f_pcap_close((pcap_t *)pcap); - return (-1); - } - - /* Save the callback info. */ - poll_rx = func; - poll_arg = arg; - - network_thread_init(); - - pclog(" Starting thread..\n"); - thread_started = thread_create_event(); - poll_tid = thread_create(poll_thread, mac); - thread_wait_event((event_t *)thread_started, -1); + poll_tid = NULL; + poll_state = NULL; + poll_card = NULL; return(0); } @@ -250,166 +219,119 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) /* Close up shop. */ void -network_pcap_close(void) +net_pcap_close(void) { pcap_t *pc; - if (pcap != NULL) { - pclog("Closing WinPcap\n"); + if (pcap == NULL) return; - /* Tell the polling thread to shut down. */ - pc = (pcap_t *)pcap; pcap = NULL; + pclog("PCAP: closing.\n"); - /* Tell the thread to terminate. */ - if (poll_tid != NULL) { - network_busy(0); + /* Tell the polling thread to shut down. */ + pc = (pcap_t *)pcap; pcap = NULL; - /* Wait for the end event. */ - pclog("Waiting for network thread to end...\n"); - network_wait_for_end((void *)poll_tid); - pclog("Network thread ended\n"); + /* Tell the thread to terminate. */ + if (poll_tid != NULL) { + network_busy(0); - poll_tid = NULL; - } + /* Wait for the thread to finish. */ + pclog("PCAP: waiting for thread to end...\n"); + thread_wait_event(poll_state, -1); + pclog("PCAP: thread ended\n"); + thread_destroy_event(poll_state); - if (thread_started) { - thread_destroy_event((event_t *)thread_started); - thread_started = NULL; - } - - /* OK, now shut down WinPcap itself. */ - f_pcap_close(pc); - pcap = NULL; - - /* Unload the DLL if possible. */ - if (pcap_handle != NULL) { - dynld_close((void *)pcap_handle); - pcap_handle = NULL; - } + poll_tid = NULL; + poll_state = NULL; + poll_card = NULL; } - poll_rx = NULL; - poll_arg = NULL; -} - -void -network_pcap_stop(void) -{ - /* OK, now shut down WinPcap itself. */ - f_pcap_close((pcap_t *)pcap); + /* OK, now shut down Pcap itself. */ + f_pcap_close(pc); pcap = NULL; +#if 0 + // no, we don't.. /* Unload the DLL if possible. */ if (pcap_handle != NULL) { dynld_close((void *)pcap_handle); pcap_handle = NULL; } +#endif } -/* Test WinPcap - 1 = success, 0 = failure. */ -// FIXME: this will be deleted. --FvK +/* + * Reset (Win)Pcap and activate it. + * + * This is called on every 'cycle' of the emulator, + * if and as long the NetworkType is set to PCAP, + * and also as long as we have a NetCard defined. + * + * We already know we have PCAP available, as this + * is called when the network activates itself and + * tries to attach to the network module. + */ int -network_pcap_test(void) +net_pcap_reset(netcard_t *card) { - char temp[PCAP_ERRBUF_SIZE]; + char errbuf[PCAP_ERRBUF_SIZE]; char filter_exp[255]; struct bpf_program fp; - char *dev; - /* Did we already load the DLL? */ - if (pcap_handle == NULL) - { - pcap_handle = dynld_module("wpcap.dll", pcap_imports); - } - -#if 1 - /* Get the value of our capture interface. */ - dev = network_pcap; - if (dev == NULL) { - pclog(" PCap device is a null pointer!\n"); - return 0; - } - if ((dev[0] == '\0') || !strcmp(dev, "none")) { - pclog(" No network device configured!\n"); - return 0; - } - pclog(" Network interface: '%s'\n", dev); -#endif - - strcpy(temp, f_pcap_lib_version()); - dev = strchr(temp, '('); - if (dev != NULL) *(dev-1) = '\0'; - pclog("PCAP: initializing, %s\n", temp); - -#if 0 - /* Get the value of our capture interface. */ - dev = network_pcap; - if ((dev[0] == '\0') || !strcmp(dev, "none")) { - pclog(" No network device configured!\n"); - - /* Unload the DLL if possible. */ - if (pcap_handle != NULL) { - dynld_close((void *) pcap_handle); - pcap_handle = NULL; - } - - return 0; - } - pclog(" Network interface: '%s'\n", dev); -#else - dev = network_pcap; -#endif - - pcap = f_pcap_open_live(dev, /* interface name */ - 1518, /* maximum packet size */ - 1, /* promiscuous mode? */ - 10, /* timeout in msec */ - temp); /* error buffer */ - if (pcap == NULL) { - pclog(" Unable to open device: %s!\n", temp); - - /* Unload the DLL if possible. */ - if (pcap_handle != NULL) { - dynld_close((void *) pcap_handle); - pcap_handle = NULL; - } - - return 0; + /* Open a PCAP live channel. */ + if ((pcap = f_pcap_open_live(network_pcap, /* interface name */ + 1518, /* max packet size */ + 1, /* promiscuous mode? */ + 10, /* timeout in msec */ + errbuf)) == NULL) { /* error buffer */ + pclog(" Unable to open device: %s!\n", network_pcap); + return(-1); } + pclog("PCAP: interface: %s\n", network_pcap); /* Create a MAC address based packet filter. */ + pclog("PCAP: installing filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + card->mac[0], card->mac[1], card->mac[2], + card->mac[3], card->mac[4], card->mac[5]); sprintf(filter_exp, "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", - 0, 1, 2, 3, 4, 5, - 0, 1, 2, 3, 4, 5); - if (f_pcap_compile((pcap_t *) pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { - if (f_pcap_setfilter((pcap_t *) pcap, &fp) == -1) { - pclog(" Error installing filter (%s) !\n", filter_exp); - network_pcap_stop(); - return 0; + card->mac[0], card->mac[1], card->mac[2], + card->mac[3], card->mac[4], card->mac[5], + card->mac[0], card->mac[1], card->mac[2], + card->mac[3], card->mac[4], card->mac[5]); + if (f_pcap_compile((pcap_t *)pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { + if (f_pcap_setfilter((pcap_t *)pcap, &fp) != 0) { + pclog("PCAP: error installing filter (%s) !\n", filter_exp); + f_pcap_close((pcap_t *)pcap); + return(-1); } } else { - pclog(" Could not compile filter (%s) !\n", filter_exp); - network_pcap_stop(); - return 0; + pclog("PCAP: could not compile filter (%s) !\n", filter_exp); + f_pcap_close((pcap_t *)pcap); + return(-1); } - network_pcap_stop(); + /* Save the callback info. */ + poll_card = card; - return 1; + pclog("PCAP: starting thread..\n"); + poll_state = thread_create_event(); + poll_tid = thread_create(poll_thread, card->mac); + thread_wait_event(poll_state, -1); + + return(0); } /* Send a packet to the Pcap interface. */ void -network_pcap_in(uint8_t *bufp, int len) +net_pcap_in(uint8_t *bufp, int len) { - if (pcap != NULL) { - network_busy(1); + if (pcap == NULL) return; - f_pcap_sendpacket((pcap_t *) pcap, bufp, len); + network_busy(1); - network_busy(0); - } + f_pcap_sendpacket((pcap_t *)pcap, bufp, len); + + network_busy(0); } diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 6b30c9f37..32eb56274 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -8,7 +8,7 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.10 2017/10/16 + * Version: @(#)net_slirp.c 1.0.11 2017/10/28 * * Author: Fred N. van Kempen, * @@ -29,22 +29,12 @@ #include "network.h" -static volatile - queueADT slirpq; /* SLiRP library handle */ -static volatile - thread_t *poll_tid; -static volatile - NETRXCB poll_rx; /* network RX function to call */ -static volatile - void *poll_arg; /* network RX function arg */ -static volatile - event_t *thread_started; +static volatile queueADT slirpq; /* SLiRP library handle */ +static volatile thread_t *poll_tid; +static netcard_t *poll_card; /* netcard attached to us */ +static event_t *poll_state; - -/* Instead of calling this and crashing some times - or experencing jitter, this is called by the - 60Hz clock which seems to do the job. */ static void slirp_tic(void) { @@ -76,60 +66,60 @@ slirp_tic(void) /* Handle the receiving of frames. */ static void -poll_thread(void *arg) +poll_thread(UNUSED(void *arg)) { struct queuepacket *qp; event_t *evt; - thread_set_event((event_t *) thread_started); - - pclog("SLiRP: polling thread started, arg %08lx\n", arg); + pclog("SLiRP: polling started.\n"); + thread_set_event(poll_state); /* Create a waitable event. */ evt = thread_create_event(); while (slirpq != NULL) { - network_mutex_wait(1); + /* Request ownership of the queue. */ + network_wait(1); - network_wait_for_poll(); + /* Wait for a poll request. */ + network_poll(); /* See if there is any work. */ slirp_tic(); /* Wait for the next packet to arrive. */ - if (QueuePeek(slirpq) == 0) { - /* If we did not get anything, wait a while. */ - thread_wait_event(evt, 10); - - network_mutex_wait(0); - continue; - } - - /* Grab a packet from the queue. */ - qp = QueueDelete(slirpq); + if (QueuePeek(slirpq) != 0) { + /* Grab a packet from the queue. */ + qp = QueueDelete(slirpq); #if 0 - pclog("SLiRP: inQ:%d got a %dbyte packet @%08lx\n", + pclog("SLiRP: inQ:%d got a %dbyte packet @%08lx\n", QueuePeek(slirpq), qp->len, qp); #endif - if (poll_rx != NULL) - poll_rx((void *) poll_arg, (uint8_t *)&qp->data, qp->len); + poll_card->rx(poll_card->priv, (uint8_t *)qp->data, qp->len); - /* Done with this one. */ - free(qp); + /* Done with this one. */ + free(qp); + } else { + /* If we did not get anything, wait a while. */ + thread_wait_event(evt, 10); + } - network_mutex_wait(0); + /* Release ownership of the queue. */ + network_wait(0); } + /* No longer needed. */ thread_destroy_event(evt); pclog("SLiRP: polling stopped.\n"); + thread_set_event(poll_state); } -/* Initialize SLiRP for us. */ +/* Initialize SLiRP for use. */ int -network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) +net_slirp_init(void) { pclog("SLiRP: initializing..\n"); @@ -139,107 +129,79 @@ network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) } slirpq = QueueCreate(); - pclog(" Packet queue is at %08lx\n", &slirpq); + poll_tid = NULL; + poll_state = NULL; + poll_card = NULL; + + return(0); +} + + +/* Initialize SLiRP for use. */ +int +net_slirp_reset(netcard_t *card) +{ /* Save the callback info. */ - poll_rx = func; - poll_arg = arg; + poll_card = card; - network_thread_init(); - - thread_started = thread_create_event(); - - pclog("SLiRP: starting thread..\n"); - poll_tid = thread_create(poll_thread, mac); - - thread_wait_event((event_t *) thread_started, -1); + pclog("SLiRP: creating thread..\n"); + poll_state = thread_create_event(); + poll_tid = thread_create(poll_thread, card->mac); + thread_wait_event(poll_state, -1); return(0); } void -network_slirp_close(void) +net_slirp_close(void) { queueADT sl; - if (slirpq != NULL) { - pclog("Closing SLiRP\n"); + if (slirpq == NULL) return; - /* Tell the polling thread to shut down. */ - sl = slirpq; slirpq = NULL; + pclog("SLiRP: closing.\n"); -#if 0 -#if 1 - /* Terminate the polling thread. */ - if (poll_tid != NULL) { - thread_kill(poll_tid); - poll_tid = NULL; - } -#else - /* Wait for the polling thread to shut down. */ - while (poll_tid != NULL) - ; -#endif -#endif + /* Tell the polling thread to shut down. */ + sl = slirpq; slirpq = NULL; - /* Tell the thread to terminate. */ - if (poll_tid != NULL) { - network_busy(0); + /* Tell the thread to terminate. */ + if (poll_tid != NULL) { + network_busy(0); - pclog("Waiting for network thread to end...\n"); - /* Wait for the end event. */ - network_wait_for_end((void *) poll_tid); - pclog("Network thread ended\n"); + /* Wait for the thread to finish. */ + pclog("SLiRP: waiting for thread to end...\n"); + thread_wait_event(poll_state, -1); + pclog("SLiRP: thread ended\n"); + thread_destroy_event(poll_state); - poll_tid = NULL; - } - - if (thread_started) { - thread_destroy_event((event_t *) thread_started); - thread_started = NULL; - } - - /* OK, now shut down SLiRP itself. */ - QueueDestroy(sl); - slirp_exit(0); + poll_tid = NULL; + poll_state = NULL; + poll_card = NULL; } - poll_rx = NULL; - poll_arg = NULL; -} - - -/* Test SLiRP - 1 = success, 0 = failure. */ -int -network_slirp_test(void) -{ - if (slirp_init() != 0) { - pclog("SLiRP could not be initialized!\n"); - return 0; - } - else - { - slirp_exit(0); - return 1; - } + /* OK, now shut down SLiRP itself. */ + QueueDestroy(sl); + slirp_exit(0); } /* Send a packet to the SLiRP interface. */ void -network_slirp_in(uint8_t *pkt, int pkt_len) +net_slirp_in(uint8_t *pkt, int pkt_len) { - if (slirpq != NULL) { - network_busy(1); + if (slirpq == NULL) return; - slirp_input((const uint8_t *)pkt, pkt_len); + network_busy(1); - network_busy(0); - } + slirp_input((const uint8_t *)pkt, pkt_len); + + network_busy(0); } +/* Needed by SLiRP library. */ void slirp_output(const uint8_t *pkt, int pkt_len) { @@ -254,6 +216,7 @@ slirp_output(const uint8_t *pkt, int pkt_len) } +/* Needed by SLiRP library. */ int slirp_can_output(void) { diff --git a/src/network/network.c b/src/network/network.c index 0bb9091bc..36e33b473 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.17 2017/10/19 + * Version: @(#)network.c 1.0.18 2017/10/28 * * Author: Fred N. van Kempen, * @@ -57,78 +57,53 @@ char network_pcap[512]; #ifdef ENABLE_NIC_LOG int nic_do_log = ENABLE_NIC_LOG; #endif -static volatile mutex_t *netMutex; +static mutex_t *network_mutex; -static struct -{ - volatile int - busy, - queue_in_use; +static struct { + volatile int busy, + queue_in_use; - volatile event_t - *wake_poll_thread, - *poll_complete, - *queue_not_in_use; + event_t *wake_poll_thread, + *poll_complete, + *queue_not_in_use; } poll_data; void -network_mutex_wait(uint8_t wait) +network_wait(uint8_t wait) { if (wait) - thread_wait_mutex((mutex_t *) netMutex); - else - thread_release_mutex((mutex_t *) netMutex); + thread_wait_mutex(network_mutex); + else + thread_release_mutex(network_mutex); } void -network_wait_for_poll() +network_poll(void) { while (poll_data.busy) - thread_wait_event((event_t *) poll_data.wake_poll_thread, -1); - thread_reset_event((event_t *) poll_data.wake_poll_thread); + thread_wait_event(poll_data.wake_poll_thread, -1); + + thread_reset_event(poll_data.wake_poll_thread); } -void -network_wait_for_end(void *handle) -{ - thread_wait((event_t *) handle, -1); - - if (poll_data.wake_poll_thread) { - thread_destroy_event((event_t *) poll_data.wake_poll_thread); - poll_data.wake_poll_thread = NULL; - } - - if (poll_data.poll_complete) { - thread_destroy_event((event_t *) poll_data.poll_complete); - poll_data.poll_complete = NULL; - } -} - - -void -network_thread_init(void) -{ - poll_data.wake_poll_thread = thread_create_event(); - poll_data.poll_complete = thread_create_event(); -} - void network_busy(uint8_t set) { poll_data.busy = !!set; - if (!set) - thread_set_event((event_t *) poll_data.wake_poll_thread); + + if (! set) + thread_set_event(poll_data.wake_poll_thread); } void network_end(void) { - thread_set_event((event_t *) poll_data.poll_complete); + thread_set_event(poll_data.poll_complete); } @@ -154,12 +129,9 @@ network_init(void) network_ndev = 1; /* Initialize the Pcap system module, if present. */ - i = network_pcap_init(&network_devs[network_ndev]); + i = net_pcap_prepare(&network_devs[network_ndev]); if (i > 0) network_ndev += i; - - if (network_type != NET_TYPE_PCAP) - network_pcap_close(); } @@ -170,35 +142,30 @@ network_init(void) * finished initializing itself, to link itself to the platform support * modules. */ -int +void network_attach(void *dev, uint8_t *mac, NETRXCB rx) { - int ret = -1; + if (network_card == 0) return; - if (network_card == 0) return(ret); - - /* Save the card's callback info. */ + /* Save the card's info. */ net_cards[network_card].priv = dev; net_cards[network_card].rx = rx; + net_cards[network_card].mac = mac; - netMutex = thread_create_mutex(L"86Box.NetMutex"); + /* Create the network events. */ + poll_data.wake_poll_thread = thread_create_event(); + poll_data.poll_complete = thread_create_event(); - /* Start the platform module. */ + /* Activate the platform module. */ switch(network_type) { case NET_TYPE_PCAP: - ret = network_pcap_setup(mac, rx, dev); - if (ret < 0) { - ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2139); - network_type = NET_TYPE_NONE; - } + (void)net_pcap_reset(&net_cards[network_card]); break; case NET_TYPE_SLIRP: - ret = network_slirp_setup(mac, rx, dev); + (void)net_slirp_reset(&net_cards[network_card]); break; } - - return(ret); } @@ -206,35 +173,30 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) void network_close(void) { - thread_close_mutex((mutex_t *) netMutex); + /* If already closed, do nothing. */ + if (network_mutex == NULL) return; - switch(network_type) { - case NET_TYPE_PCAP: - network_pcap_close(); - break; + /* Force-close the PCAP module. */ + net_pcap_close(); - case NET_TYPE_SLIRP: - network_slirp_close(); - break; + /* Force-close the SLIRP module. */ + net_slirp_close(); + + /* Close the network events. */ + if (poll_data.wake_poll_thread != NULL) { + thread_destroy_event(poll_data.wake_poll_thread); + poll_data.wake_poll_thread = NULL; } -} - - -/* Test the network. */ -int -network_test(void) -{ - switch(network_type) { - case NET_TYPE_PCAP: - return network_pcap_test(); - break; - - case NET_TYPE_SLIRP: - return network_slirp_test(); - break; + if (poll_data.poll_complete != NULL) { + thread_destroy_event(poll_data.poll_complete); + poll_data.poll_complete = NULL; } - return 0; + /* Close the network thread mutex. */ + thread_close_mutex(network_mutex); + network_mutex = NULL; + + pclog("NETWORK: closed.\n"); } @@ -249,7 +211,10 @@ network_test(void) void network_reset(void) { + int i = -1; + pclog("NETWORK: reset (type=%d, card=%d)\n", network_type, network_card); + ui_sb_update_icon(SB_NETWORK, 0); /* Just in case.. */ network_close(); @@ -257,11 +222,36 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; - if (network_type==NET_TYPE_PCAP) network_pcap_reset(); + network_mutex = thread_create_mutex(L"86Box.NetMutex"); + + /* Initialize the platform module. */ + switch(network_type) { + case NET_TYPE_PCAP: + i = net_pcap_init(); + break; + + case NET_TYPE_SLIRP: + i = net_slirp_init(); + break; + } + + if (i < 0) { + /* Tell user we can't do this (at the moment.) */ + ui_msgbox(MBX_ERROR, (wchar_t *)IDS_2139); + + // FIXME: we should ask in the dialog if they want to + // reconfigure or quit, and throw them into the + // Settings dialog if yes. + + /* Disable network. */ + network_type = NET_TYPE_NONE; + + return; + } pclog("NETWORK: set up for %s, card='%s'\n", - (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", - net_cards[network_card].name); + (network_type==NET_TYPE_SLIRP)?"SLiRP":"Pcap", + net_cards[network_card].name); /* Add the (new?) card to the I/O system. */ if (net_cards[network_card].device) { @@ -276,15 +266,45 @@ network_reset(void) void network_tx(uint8_t *bufp, int len) { + ui_sb_update_icon(SB_NETWORK, 1); + switch(network_type) { case NET_TYPE_PCAP: - network_pcap_in(bufp, len); + net_pcap_in(bufp, len); break; case NET_TYPE_SLIRP: - network_slirp_in(bufp, len); + net_slirp_in(bufp, len); break; } + + ui_sb_update_icon(SB_NETWORK, 0); +} + + +int +network_dev_to_id(char *devname) +{ + int i = 0; + + for (i=0; i */ @@ -38,6 +38,7 @@ typedef struct { void *priv; int (*poll)(void *); NETRXCB rx; + uint8_t *mac; } netcard_t; typedef struct { @@ -47,42 +48,37 @@ typedef struct { /* Global variables. */ -extern int nic_do_log; -extern int network_card; -extern int network_type; +extern int nic_do_log; /* config */ +extern int network_card; /* config */ +extern int network_type; /* config */ +extern char network_pcap[512]; /* config */ extern int network_ndev; extern netdev_t network_devs[32]; -extern char network_pcap[512]; /* Function prototypes. */ -extern void network_mutex_wait(uint8_t wait); -extern void network_wait_for_poll(void); -extern void network_wait_for_end(void *handle); -extern void network_mutex_init(void); -extern void network_thread_init(void); +extern void network_wait(uint8_t wait); +extern void network_poll(void); extern void network_busy(uint8_t set); extern void network_end(void); extern void network_init(void); -extern int network_attach(void *, uint8_t *, NETRXCB); +extern void network_attach(void *, uint8_t *, NETRXCB); extern void network_close(void); -extern int network_test(void); extern void network_reset(void); +extern int network_available(void); extern void network_tx(uint8_t *, int); -extern int network_pcap_init(netdev_t *); -extern void network_pcap_reset(void); -extern int network_pcap_setup(uint8_t *, NETRXCB, void *); -extern void network_pcap_close(void); -extern int network_pcap_test(void); -extern void network_pcap_in(uint8_t *, int); +extern int net_pcap_prepare(netdev_t *); +extern int net_pcap_init(void); +extern int net_pcap_reset(netcard_t *); +extern void net_pcap_close(void); +extern void net_pcap_in(uint8_t *, int); -extern void network_slirp_mutex_init(void); -extern int network_slirp_setup(uint8_t *, NETRXCB, void *); -extern void network_slirp_close(void); -extern int network_slirp_test(void); -extern void network_slirp_in(uint8_t *, int); +extern int net_slirp_init(void); +extern int net_slirp_reset(netcard_t *); +extern void net_slirp_close(void); +extern void net_slirp_in(uint8_t *, int); extern int network_dev_to_id(char *); extern int network_card_available(int); diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index e2dfbe785..4d2c848ef 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -10,7 +10,7 @@ * * Based on the "libpcap" examples. * - * Version: @(#)pcap_if.c 1.0.6 2017/10/27 + * Version: @(#)pcap_if.c 1.0.7 2017/10/28 * * Author: Fred N. van Kempen, * @@ -237,13 +237,13 @@ main(int argc, char **argv) int numdev, i; /* Try loading the DLL. */ -#ifdef WIN32 +#ifdef _WIN32 pcap_handle = dynld_module("wpcap.dll", pcap_imports); #else pcap_handle = dynld_module("libpcap.so", pcap_imports); #endif if (pcap_handle == NULL) { -#ifdef WIN32 +#ifdef _WIN32 fprintf(stderr, "Unable to load WinPcap DLL !\n"); #else fprintf(stderr, "Unable to load libpcap.so !\n"); diff --git a/src/network/slirp/debug.c b/src/network/slirp/debug.c index 50cae86a7..9e727732a 100644 --- a/src/network/slirp/debug.c +++ b/src/network/slirp/debug.c @@ -6,7 +6,7 @@ * terms and conditions of the copyright. */ -#ifndef WIN32 +#ifndef _WIN32 # include #endif #include "slirp.h" diff --git a/src/network/slirp/misc.c b/src/network/slirp/misc.c index 0da04dee2..fe6f84a84 100644 --- a/src/network/slirp/misc.c +++ b/src/network/slirp/misc.c @@ -7,7 +7,7 @@ #define WANT_SYS_IOCTL_H #include -#ifndef WIN32 +#ifndef _WIN32 # include #endif #include "slirp.h" @@ -223,12 +223,6 @@ add_exec(ex_ptr, do_pty, exec, addr, port) /* * For systems with no strerror */ - -#ifdef WIN32 -//extern int sys_nerr; -//extern char *sys_errlist[]; -#endif - char * SLIRPstrerror(error) int error; diff --git a/src/network/slirp/socket.c b/src/network/slirp/socket.c index fba38fc79..a930c502d 100644 --- a/src/network/slirp/socket.c +++ b/src/network/slirp/socket.c @@ -7,7 +7,7 @@ #define WANT_SYS_IOCTL_H #include -#ifndef WIN32 +#ifndef _WIN32 # include #endif #include "slirp.h" diff --git a/src/network/slirp/tcp_subr.c b/src/network/slirp/tcp_subr.c index 5168e4ae4..5f04b0730 100644 --- a/src/network/slirp/tcp_subr.c +++ b/src/network/slirp/tcp_subr.c @@ -40,7 +40,7 @@ #define WANT_SYS_IOCTL_H #include -#ifndef WIN32 +#ifndef _WIN32 # include #endif #include "slirp.h" diff --git a/src/network/slirp/udp.c b/src/network/slirp/udp.c index 7c7d0831b..f847c51a4 100644 --- a/src/network/slirp/udp.c +++ b/src/network/slirp/udp.c @@ -39,7 +39,7 @@ */ #include -#ifndef WIN32 +#ifndef _WIN32 # include #endif #include "slirp.h" diff --git a/src/nvr.c b/src/nvr.c index 78ecd1698..776420629 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -186,7 +186,7 @@ * (DS12887A) which implemented a "century" register to be * compatible with Y2K. * - * Version: @(#)nvr.c 1.0.10 2017/10/16 + * Version: @(#)nvr.c 1.0.11 2017/10/28 * * Authors: Sarah Walker, * Miran Grca, @@ -760,7 +760,7 @@ nvr_path(wchar_t *str) plat_dir_create(temp); /* Now append the actual filename. */ -#ifdef WIN32 +#ifdef _WIN32 wcscat(temp, L"\\"); #else wcscat(temp, L"/"); diff --git a/src/pc.c b/src/pc.c index 10f3bb955..ab2a1b324 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.35 2017/10/27 + * Version: @(#)pc.c 1.0.37 2017/10/28 * * Authors: Sarah Walker, * Miran Grca, @@ -50,6 +50,7 @@ #include "keyboard_at.h" #include "lpt.h" #include "serial.h" +#include "bugger.h" #include "cdrom/cdrom.h" #include "disk/hdd.h" #include "disk/hdc.h" @@ -133,6 +134,7 @@ wchar_t exe_path[1024]; /* path (dir) of executable */ wchar_t cfg_path[1024]; /* path (dir) of user data */ int scrnsz_x = SCREEN_RES_X, /* current screen size, X */ scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */ +int config_changed; /* configuration has changed */ int title_update; int64_t main_time; @@ -366,7 +368,7 @@ usage: /* Make sure cfg_path has a trailing backslash. */ if ((cfg_path[wcslen(cfg_path)-1] != L'\\') && (cfg_path[wcslen(cfg_path)-1] != L'/')) { -#ifdef WIN32 +#ifdef _WIN32 wcscat(cfg_path, L"\\"); #else wcscat(cfg_path, L"/"); @@ -382,7 +384,7 @@ usage: * Otherwise, assume the pathname given is * relative to whatever the cfg_path is. */ -#ifdef WIN32 +#ifdef _WIN32 if ((cfg[1] == L':') || /* drive letter present */ (cfg[0] == L'\\')) /* backslash, root dir */ #else @@ -632,9 +634,10 @@ pc_reset_hard_close(void) void pc_reset_hard_init(void) { - /* First, we reset the modules that are not part of the - * actual machine, but which support some of the modules - * that are. + /* + * First, we reset the modules that are not part of + * the actual machine, but which support some of the + * modules that are. */ sound_realloc_buffers(); sound_cd_thread_reset(); @@ -719,8 +722,25 @@ pc_reset_hard_init(void) if (SSI2001) device_add(&ssi2001_device); + if (joystick_type != 7) + gameport_update_joystick_type(); + + if (config_changed) { +pclog("PC: configuration changed, updating status bar and saving..\n"); + ui_sb_update_panes(); + + config_save(); + + config_changed = 0; + } + + /* Needs the status bar... */ + if (bugger_enabled) + device_add(&bugger_device); + /* Reset the CPU module. */ cpu_set(); + cpu_update_waitstates(); cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; resetx86(); dma_reset(); @@ -728,10 +748,7 @@ pc_reset_hard_init(void) shadowbios = 0; - if (AT) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu].rspeed); - else - setpitclock(14318184.0); + pc_speed_changed(); } @@ -792,11 +809,11 @@ pc_close(thread_t *ptr) for (i=0; iexit(i); - dumppic(); - for (i=0; i * Fred N. van Kempen, @@ -24,12 +24,16 @@ #endif -#ifndef WIN32 +#ifndef _WIN32 # define RENDER_FPS 70 /* default render speed */ #endif +/* The Win32 API uses _wcsicmp. */ +#ifdef _WIN32 +# define wcscasecmp _wcsicmp +#endif -#ifdef FREEBSD +#if defined(UNIX) && defined(FREEBSD) /* FreeBSD has largefile by default. */ # define fopen64 fopen # define fseeko64 fseeko @@ -38,9 +42,12 @@ #endif -/* A hack (GCC-specific) to allow us to ignore unused parameters. */ +/* A hack (GCC-specific?) to allow us to ignore unused parameters. */ #define UNUSED(arg) __attribute__((unused))arg +/* Return the size (in wchar's) of a wchar_t array. */ +#define sizeof_w(x) (sizeof((x)) / sizeof(wchar_t)) + #ifdef __cplusplus extern "C" { @@ -80,15 +87,6 @@ extern void plat_setfullscreen(int on); extern void plat_resize(int max_x, int max_y); -/* Return the size (in wchar's) of a wchar_t array. */ -#define sizeof_w(x) (sizeof((x)) / sizeof(wchar_t)) - -/* The Win32 API uses _wcsicmp. */ -#ifdef WIN32 -# define wcscasecmp _wcsicmp -#endif - - /* Resource management. */ extern wchar_t *plat_get_string(int id); extern wchar_t *plat_get_string_from_string(char *str); diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index c88f2cefc..808cbfffc 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -222,7 +222,7 @@ void* fluidsynth_init(device_t *info) memset(data, 0, sizeof(fluidsynth_t)); /* Try loading the DLL. */ -#ifdef WIN32 +#ifdef _WIN32 fluidsynth_handle = dynld_module("libfluidsynth.dll", fluidsynth_imports); #else fluidsynth_handle = dynld_module("libfluidsynth.so", fluidsynth_imports); diff --git a/src/ui.h b/src/ui.h index dca1dd585..b23b7d5ab 100644 --- a/src/ui.h +++ b/src/ui.h @@ -8,7 +8,7 @@ * * Define the various UI functions. * - * Version: @(#)ui.h 1.0.7 2017/10/26 + * Version: @(#)ui.h 1.0.8 2017/10/28 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -25,9 +25,10 @@ extern "C" { #endif /* Strings. Those are defined within the platform. */ -#ifdef WIN32 +#ifdef _WIN32 # include "win/resource.h" -#else +#endif +#ifdef UNIX # include "unix/resource.h" #endif diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index cf9b74062..c295a5504 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -8,7 +8,7 @@ * * Emulation of the 3DFX Voodoo Graphics controller. * - * Version: @(#)vid_voodoo.c 1.0.3 2017/10/16 + * Version: @(#)vid_voodoo.c 1.0.4 2017/10/28 * * Authors: Sarah Walker, * leilei @@ -2563,7 +2563,7 @@ static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t state->tex_a[0] ^= 0xff; } -#if ((defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__) && (defined USE_DYNAREC)) +#if ((defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32) && !(defined __amd64__) && (defined USE_DYNAREC)) #include "vid_voodoo_codegen_x86.h" #elif ((defined __amd64__) && (defined USE_DYNAREC)) #include "vid_voodoo_codegen_x86-64.h" diff --git a/src/video/vid_voodoo_codegen_x86.h b/src/video/vid_voodoo_codegen_x86.h index 2e5f5e314..6ef8383f8 100644 --- a/src/video/vid_voodoo_codegen_x86.h +++ b/src/video/vid_voodoo_codegen_x86.h @@ -9,7 +9,7 @@ #include #include #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 +#ifdef _WIN32 #define BITMAP windows_BITMAP #include #undef BITMAP @@ -3285,7 +3285,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) long pagemask = ~(pagesize - 1); #endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 +#ifdef _WIN32 voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else voodoo->codegen_data = malloc(sizeof(voodoo_x86_data_t) * BLOCK_NUM*2); @@ -3325,7 +3325,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) static void voodoo_codegen_close(voodoo_t *voodoo) { -#if defined WIN32 || defined _WIN32 || defined _WIN32 +#ifdef _WIN32 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else free(voodoo->codegen_data); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 76d8def60..a061ad1ec 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.69 2017/10/26 +# Version: @(#)Makefile.mingw 1.0.70 2017/10/28 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -117,7 +117,7 @@ DEPS = -MMD -MF $*.d -c $< DEPFILE := win/.depends # Set up the correct toolchain flags. -OPTS := -DWIN32 $(EXTRAS) $(STUFF) +OPTS := $(EXTRAS) $(STUFF) ifdef EXFLAGS OPTS += $(EXFLAGS) endif diff --git a/src/win/win.c b/src/win/win.c index 19cf5a1ec..78b8b43e3 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -6,9 +6,9 @@ * * This file is part of the 86Box distribution. * - * The Emulator's Windows core. + * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.29 2017/10/24 + * Version: @(#)win.c 1.0.30 2017/10/28 * * Authors: Sarah Walker, * Miran Grca, @@ -561,7 +561,6 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) rom_load_bios(romset); network_init(); ResetAllMenus(); - ui_sb_update_panes(); pc_reset_hard_init(); } } diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 56e00b759..95a7a8111 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.21 2017/10/16 + * Version: @(#)win_settings.c 1.0.22 2017/10/28 * * Author: Miran Grca, * @@ -378,6 +378,12 @@ static void win_settings_save(void) } memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + /* Mark configuration as changed. */ + config_changed = 1; + +#if 1 + pc_reset_hard_init(); +#else mem_resize(); rom_load_bios(romset); @@ -396,6 +402,7 @@ static void win_settings_save(void) pc_speed_changed(); if (joystick_type != 7) gameport_update_joystick_type(); +#endif } diff --git a/src/win/win_stbar.c b/src/win/win_stbar.c index b3fd18887..f20fe3530 100644 --- a/src/win/win_stbar.c +++ b/src/win/win_stbar.c @@ -8,7 +8,7 @@ * * Implement the application's Status Bar. * - * Version: @(#)win_stbar.c 1.0.3 2017/10/16 + * Version: @(#)win_stbar.c 1.0.4 2017/10/28 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -119,15 +119,6 @@ hdd_count(int bus) } -static int -display_network_icon(void) -{ - if ((network_type == 0) || (network_card == 0)) return(0); - - return(network_test()); -} - - static void StatusBarCreateFloppySubmenu(HMENU m, int id) { @@ -530,7 +521,7 @@ ui_sb_update_panes(void) c_ide_pio = hdd_count(HDD_BUS_IDE_PIO_ONLY); c_ide_dma = hdd_count(HDD_BUS_IDE_PIO_AND_DMA); c_scsi = hdd_count(HDD_BUS_SCSI); - do_net = display_network_icon(); + do_net = network_available(); if (sb_parts > 0) { for (i = 0; i < sb_parts; i++) @@ -1075,9 +1066,29 @@ StatusBarCreate(HWND hwndParent, int idStatus, HINSTANCE hInst) /* Load the dummu menu for this window. */ menuSBAR = LoadMenu(hInst, SB_MENU_NAME); - /* Initialize the status bar and populate the icons and menus. */ + /* Initialize the status bar. This is clumsy. */ + sb_parts = 1; + iStatusWidths = (int *)malloc(sb_parts * sizeof(int)); + memset(iStatusWidths, 0, sb_parts * sizeof(int)); + sb_part_meanings = (int *)malloc(sb_parts * sizeof(int)); + memset(sb_part_meanings, 0, sb_parts * sizeof(int)); + sb_part_icons = (int *)malloc(sb_parts * sizeof(int)); + memset(sb_part_icons, 0, sb_parts * sizeof(int)); + sb_icon_flags = (int *)malloc(sb_parts * sizeof(int)); + memset(sb_icon_flags, 0, sb_parts * sizeof(int)); + sb_menu_handles = (HMENU *)malloc(sb_parts * sizeof(HMENU)); + memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); + sbTips = (WCHAR **)malloc(sb_parts * sizeof(WCHAR *)); + memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); sb_parts = 0; - ui_sb_update_panes(); + iStatusWidths[sb_parts] = -1; + sb_part_meanings[sb_parts] = SB_TEXT; + sb_part_icons[sb_parts] = -1; + sb_parts++; + SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)sb_parts, (LPARAM)iStatusWidths); + SendMessage(hwndSBAR, SB_SETTEXT, 0 | SBT_NOBORDERS, + (LPARAM)L"Welcome to 86Box !"); + sb_ready = 1; } diff --git a/src/win/win_video.c b/src/win/win_video.c index 952b0fe92..c9a4532c2 100644 --- a/src/win/win_video.c +++ b/src/win/win_video.c @@ -8,7 +8,7 @@ * * Platform video API support for Win32. * - * Version: @(#)win_video.c 1.0.3 2017/10/24 + * Version: @(#)win_video.c 1.0.4 2017/10/28 * * Author: Fred N. van Kempen, * @@ -254,11 +254,7 @@ take_screenshot(void) if (! plat_dir_check(path)) plat_dir_create(path); -#ifdef WIN32 wcscat(path, L"\\"); -#else - wcscat(path, L"/"); -#endif switch(vid_api) { case 0: /* ddraw */