From 0570e21f0f560fee33efc5915e17c1626a15868a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 29 Apr 2020 23:39:54 +0200 Subject: [PATCH] Applied Ryuzaki's Media menu patch, fixed a bug in cpu.c reported by ms. person, fixed bugs (and added a workaround for the Windows 2000 PCnet problems) to mem.c, and added a network packet queue to cap network speed (and do the actual rx poll in the main thread instead) for more stability, also some ES1371 fixes (but not enough to make it work on Linux). --- src/cpu_common/cpu.c | 5 +- src/include/86box/mem.h | 4 +- src/include/86box/network.h | 10 ++++ src/mem.c | 61 ++++++--------------- src/network/net_pcap.c | 3 +- src/network/net_pcnet.c | 54 ++++++++++++++++--- src/network/net_slirp.c | 3 +- src/network/network.c | 104 ++++++++++++++++++++++++++++++++++++ src/sound/snd_audiopci.c | 19 ++++--- src/win/win_media_menu.c | 30 ----------- 10 files changed, 198 insertions(+), 95 deletions(-) diff --git a/src/cpu_common/cpu.c b/src/cpu_common/cpu.c index c77e02ca4..79728c50e 100644 --- a/src/cpu_common/cpu.c +++ b/src/cpu_common/cpu.c @@ -319,10 +319,9 @@ cpu_set(void) #else is_k5 = 0; #endif - is_k6 = (cpu_s->cpu_type == CPU_K6); is_k6 = (cpu_s->cpu_type == CPU_K6) || (cpu_s->cpu_type == CPU_K6_2) || - (cpu_s->cpu_type == CPU_K6_2C) || (cpu_s->cpu_type == CPU_K6_3) || - (cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P); + (cpu_s->cpu_type == CPU_K6_2C) || (cpu_s->cpu_type == CPU_K6_3) || + (cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P); is_p6 = (cpu_s->cpu_type == CPU_PENTIUMPRO) || (cpu_s->cpu_type == CPU_PENTIUM2) || (cpu_s->cpu_type == CPU_PENTIUM2D); /* The Samuel 2 datasheet claims it's Celeron-compatible. */ diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 25d1aac63..14fc391a3 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -46,6 +46,7 @@ #define MEM_WRITE_EXTERNAL 0x02 #define MEM_WRITE_DISABLED 0x03 #define MEM_WRITE_NORMAL 0x04 /* SMM only - means use the non-SMM state */ +#define MEM_WRITE_EXTERNAL_EX 0x05 #define MEM_WRITE_ROMCS 0x06 /* EXTERNAL type + ROMC flag */ #define MEM_WRITE_EXTANY 0x07 /* Any EXTERNAL type */ #define MEM_WRITE_MASK 0x0f @@ -201,7 +202,8 @@ extern int readlnum, extern int memspeed[11]; -extern int mmu_perm; +extern int mmu_perm, + use_phys_exec; extern int mem_a20_state, mem_a20_alt, diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 9a0916382..ac4a08d02 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -69,6 +69,14 @@ typedef int (*NETWAITCB)(void *); typedef int (*NETSETLINKSTATE)(void *); +typedef struct netpkt { + void *priv; + uint8_t *data; + int len; + + struct netpkt *prev, *next; +} netpkt_t; + typedef struct { const char *name; const char *internal_name; @@ -131,6 +139,8 @@ extern const device_t *network_card_getdevice(int); extern void network_set_wait(int wait); extern int network_get_wait(void); +extern void network_queue_put(void *priv, uint8_t *data, int len); + #ifdef __cplusplus } #endif diff --git a/src/mem.c b/src/mem.c index f5cecb775..a145c9631 100644 --- a/src/mem.c +++ b/src/mem.c @@ -115,6 +115,8 @@ uint64_t *byte_code_present_mask; uint32_t purgable_page_list_head = 0; int purgeable_page_count = 0; +int use_phys_exec = 0; + /* FIXME: re-do this with a 'mem_ops' struct. */ static mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; @@ -133,9 +135,6 @@ static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; #endif -#define USE_PHYS_EXEC - - #ifdef ENABLE_MEM_LOG int mem_do_log = ENABLE_MEM_LOG; @@ -1378,12 +1377,9 @@ mem_readb_phys(uint32_t addr) mem_logical_addr = 0xffffffff; -#ifdef USE_PHYS_EXEC - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) + if (use_phys_exec && _mem_exec[addr >> MEM_GRANULARITY_BITS]) return _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]; - else -#endif - if (map && map->read_b) + else if (map && map->read_b) return map->read_b(addr, map->p); else return 0xff; @@ -1394,20 +1390,14 @@ uint16_t mem_readw_phys(uint32_t addr) { mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - uint16_t temp; -#ifdef USE_PHYS_EXEC - uint16_t *p; -#endif + uint16_t temp, *p; mem_logical_addr = 0xffffffff; -#ifdef USE_PHYS_EXEC - if ((addr <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { + if (use_phys_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]); return *p; - } else -#endif - if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) + } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->read_w)) return map->read_w(addr, map->p); else { temp = mem_readb_phys(addr + 1) << 8; @@ -1422,20 +1412,14 @@ uint32_t mem_readl_phys(uint32_t addr) { mem_mapping_t *map = read_mapping[addr >> MEM_GRANULARITY_BITS]; - uint32_t temp; -#ifdef USE_PHYS_EXEC - uint32_t *p; -#endif + uint32_t temp, *p; mem_logical_addr = 0xffffffff; -#ifdef USE_PHYS_EXEC - if ((addr <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { + if (use_phys_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]); return *p; - } else -#endif - if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) + } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->read_l)) return map->read_l(addr, map->p); else { temp = mem_readw_phys(addr + 2) << 16; @@ -1473,12 +1457,9 @@ mem_writeb_phys(uint32_t addr, uint8_t val) mem_logical_addr = 0xffffffff; -#ifdef USE_PHYS_EXEC - if (_mem_exec[addr >> MEM_GRANULARITY_BITS]) + if (use_phys_exec && _mem_exec[addr >> MEM_GRANULARITY_BITS]) _mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK] = val; - else -#endif - if (map && map->write_b) + else if (map && map->write_b) map->write_b(addr, val, map->p); } @@ -1487,19 +1468,14 @@ void mem_writew_phys(uint32_t addr, uint16_t val) { mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; -#ifdef USE_PHYS_EXEC uint16_t *p; -#endif mem_logical_addr = 0xffffffff; -#ifdef USE_PHYS_EXEC - if ((addr <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { + if (use_phys_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { p = (uint16_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]); *p = val; - } else -#endif - if ((addr <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) + } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_HBOUND) && (map && map->write_w)) map->write_w(addr, val, map->p); else { mem_writeb_phys(addr, val & 0xff); @@ -1512,19 +1488,14 @@ void mem_writel_phys(uint32_t addr, uint32_t val) { mem_mapping_t *map = write_mapping[addr >> MEM_GRANULARITY_BITS]; -#ifdef USE_PHYS_EXEC uint32_t *p; -#endif mem_logical_addr = 0xffffffff; -#ifdef USE_PHYS_EXEC - if ((addr <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { + if (use_phys_exec && ((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (_mem_exec[addr >> MEM_GRANULARITY_BITS])) { p = (uint32_t *) &(_mem_exec[addr >> MEM_GRANULARITY_BITS][addr & MEM_GRANULARITY_MASK]); *p = val; - } else -#endif - if ((addr <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) + } else if (((addr & MEM_GRANULARITY_MASK) <= MEM_GRANULARITY_QBOUND) && (map && map->write_l)) map->write_l(addr, val, map->p); else { mem_writew_phys(addr, val & 0xffff); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index beba36ca9..0d91fa55a 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -201,7 +201,8 @@ poll_thread(void *arg) if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { - poll_card->rx(poll_card->priv, data, h.caplen); + network_queue_put(poll_card->priv, data, h.caplen); + // poll_card->rx(poll_card->priv, data, h.caplen); } else { /* Mark as invalid packet. */ data = NULL; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 70c340987..94a069013 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -441,11 +441,15 @@ pcnetTmdLoad(nic_t *dev, TMD *tmd, uint32_t addr, int fRetIfNotOwn) uint16_t xda[4]; uint32_t xda32[4]; + use_phys_exec = 1; + if (BCR_SWSTYLE(dev) == 0) { dma_bm_read(addr, (uint8_t *) bytes, 4, dev->transfer_size); ownbyte = bytes[3]; - if (!(ownbyte & 0x80) && fRetIfNotOwn) + if (!(ownbyte & 0x80) && fRetIfNotOwn) { + use_phys_exec = 0; return 0; + } dma_bm_read(addr, (uint8_t*)&xda[0], sizeof(xda), dev->transfer_size); ((uint32_t *)tmd)[0] = (uint32_t)xda[0] | ((uint32_t)(xda[1] & 0x00ff) << 16); ((uint32_t *)tmd)[1] = (uint32_t)xda[2] | ((uint32_t)(xda[1] & 0xff00) << 16); @@ -454,14 +458,18 @@ pcnetTmdLoad(nic_t *dev, TMD *tmd, uint32_t addr, int fRetIfNotOwn) } else if (BCR_SWSTYLE(dev) != 3) { dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size); ownbyte = bytes[3]; - if (!(ownbyte & 0x80) && fRetIfNotOwn) + if (!(ownbyte & 0x80) && fRetIfNotOwn) { + use_phys_exec = 0; return 0; + } dma_bm_read(addr, (uint8_t*)tmd, 16, dev->transfer_size); } else { dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size); ownbyte = bytes[3]; - if (!(ownbyte & 0x80) && fRetIfNotOwn) + if (!(ownbyte & 0x80) && fRetIfNotOwn) { + use_phys_exec = 0; return 0; + } dma_bm_read(addr, (uint8_t*)&xda32[0], sizeof(xda32), dev->transfer_size); ((uint32_t *)tmd)[0] = xda32[2]; ((uint32_t *)tmd)[1] = xda32[1]; @@ -474,6 +482,8 @@ pcnetTmdLoad(nic_t *dev, TMD *tmd, uint32_t addr, int fRetIfNotOwn) if (!(ownbyte & 0x80)) tmd->tmd1.own = 0; + use_phys_exec = 0; + return !!tmd->tmd1.own; } @@ -485,12 +495,12 @@ pcnetTmdLoad(nic_t *dev, TMD *tmd, uint32_t addr, int fRetIfNotOwn) static __inline void pcnetTmdStorePassHost(nic_t *dev, TMD *tmd, uint32_t addr) { - uint8_t bytes[4] = { 0, 0, 0, 0 }; uint16_t xda[4]; uint32_t xda32[3]; + use_phys_exec = 1; + if (BCR_SWSTYLE(dev) == 0) { - dma_bm_read(addr, (uint8_t *) bytes, sizeof(xda), dev->transfer_size); xda[0] = ((uint32_t *)tmd)[0] & 0xffff; xda[1] = ((((uint32_t *)tmd)[0] >> 16) & 0xff) | ((((uint32_t *)tmd)[1]>>16) & 0xff00); xda[2] = ((uint32_t *)tmd)[1] & 0xffff; @@ -519,6 +529,8 @@ pcnetTmdStorePassHost(nic_t *dev, TMD *tmd, uint32_t addr) xda32[1] &= ~0x80000000; dma_bm_write(addr, (uint8_t*)&xda32[0], sizeof(xda32), dev->transfer_size); } + + use_phys_exec = 0; } @@ -538,11 +550,15 @@ pcnetRmdLoad(nic_t *dev, RMD *rmd, uint32_t addr, int fRetIfNotOwn) uint16_t rda[4]; uint32_t rda32[4]; + use_phys_exec = 1; + if (BCR_SWSTYLE(dev) == 0) { dma_bm_read(addr, (uint8_t *) bytes, 4, dev->transfer_size); ownbyte = bytes[3]; - if (!(ownbyte & 0x80) && fRetIfNotOwn) + if (!(ownbyte & 0x80) && fRetIfNotOwn) { + use_phys_exec = 0; return 0; + } dma_bm_read(addr, (uint8_t*)&rda[0], sizeof(rda), dev->transfer_size); ((uint32_t *)rmd)[0] = (uint32_t)rda[0] | ((rda[1] & 0x00ff) << 16); ((uint32_t *)rmd)[1] = (uint32_t)rda[2] | ((rda[1] & 0xff00) << 16); @@ -551,14 +567,18 @@ pcnetRmdLoad(nic_t *dev, RMD *rmd, uint32_t addr, int fRetIfNotOwn) } else if (BCR_SWSTYLE(dev) != 3) { dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size); ownbyte = bytes[3]; - if (!(ownbyte & 0x80) && fRetIfNotOwn) + if (!(ownbyte & 0x80) && fRetIfNotOwn) { + use_phys_exec = 0; return 0; + } dma_bm_read(addr, (uint8_t*)rmd, 16, dev->transfer_size); } else { dma_bm_read(addr + 4, (uint8_t *) bytes, 4, dev->transfer_size); ownbyte = bytes[3]; - if (!(ownbyte & 0x80) && fRetIfNotOwn) + if (!(ownbyte & 0x80) && fRetIfNotOwn) { + use_phys_exec = 0; return 0; + } dma_bm_read(addr, (uint8_t*)&rda32[0], sizeof(rda32), dev->transfer_size); ((uint32_t *)rmd)[0] = rda32[2]; ((uint32_t *)rmd)[1] = rda32[1]; @@ -572,6 +592,8 @@ pcnetRmdLoad(nic_t *dev, RMD *rmd, uint32_t addr, int fRetIfNotOwn) if (!(ownbyte & 0x80)) rmd->rmd1.own = 0; + use_phys_exec = 0; + return !!rmd->rmd1.own; } @@ -586,6 +608,8 @@ pcnetRmdStorePassHost(nic_t *dev, RMD *rmd, uint32_t addr) uint16_t rda[4]; uint32_t rda32[3]; + use_phys_exec = 1; + if (BCR_SWSTYLE(dev) == 0) { rda[0] = ((uint32_t *)rmd)[0] & 0xffff; rda[1] = ((((uint32_t *)rmd)[0]>>16) & 0xff) | ((((uint32_t *)rmd)[1]>>16) & 0xff00); @@ -615,6 +639,8 @@ pcnetRmdStorePassHost(nic_t *dev, RMD *rmd, uint32_t addr) rda32[1] &= ~0x80000000; dma_bm_write(addr, (uint8_t*)&rda32[0], sizeof(rda32), dev->transfer_size); } + + use_phys_exec = 0; } @@ -931,8 +957,10 @@ pcnetInit(nic_t *dev) /** @todo Documentation says that RCVRL and XMTRL are stored as two's complement! * Software is allowed to write these registers directly. */ #define PCNET_INIT() do { \ + use_phys_exec = 1; \ dma_bm_read(PHYSADDR(dev, CSR_IADR(dev)), \ (uint8_t *)&initblk, sizeof(initblk), dev->transfer_size); \ + use_phys_exec = 0; \ dev->aCSR[15] = le16_to_cpu(initblk.mode); \ CSR_RCVRL(dev) = (initblk.rlen < 9) ? (1 << initblk.rlen) : 512; \ CSR_XMTRL(dev) = (initblk.tlen < 9) ? (1 << initblk.tlen) : 512; \ @@ -1338,7 +1366,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) * - we don't cache any register state beyond this point */ + use_phys_exec = 1; dma_bm_write(rbadr, src, cbBuf, dev->transfer_size); + use_phys_exec = 0; /* RX disabled in the meantime? If so, abort RX. */ if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev)) { @@ -1381,7 +1411,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) /* We have to leave the critical section here or we risk deadlocking * with EMT when the write is to an unallocated page or has an access * handler associated with it. See above for additional comments. */ + use_phys_exec = 1; dma_bm_write(rbadr2, src, cbBuf, dev->transfer_size); + use_phys_exec = 0; /* RX disabled in the meantime? If so, abort RX. */ if (CSR_DRX(dev) || CSR_STOP(dev) || CSR_SPND(dev)) { @@ -1506,7 +1538,9 @@ pcnetAsyncTransmit(nic_t *dev) * zero length if it is not the last one in the chain. */ if (cb <= MAX_FRAME) { dev->xmit_pos = cb; + use_phys_exec = 1; dma_bm_read(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb, dev->transfer_size); + use_phys_exec = 0; if (fLoopback) { if (HOST_IS_OWNER(CSR_CRST(dev))) @@ -1572,7 +1606,9 @@ pcnetAsyncTransmit(nic_t *dev) */ unsigned cb = 4096 - tmd.tmd1.bcnt; dev->xmit_pos = pcnetCalcPacketLen(dev, cb); + use_phys_exec = 1; dma_bm_read(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf, cb, dev->transfer_size); + use_phys_exec = 0; for (;;) { /* @@ -1611,7 +1647,9 @@ pcnetAsyncTransmit(nic_t *dev) if (dev->xmit_pos + cb <= MAX_FRAME) { /** @todo this used to be ... + cb < MAX_FRAME. */ int off = dev->xmit_pos; dev->xmit_pos = cb + off; + use_phys_exec = 1; dma_bm_read(PHYSADDR(dev, tmd.tmd0.tbadr), dev->abLoopBuf + off, cb, dev->transfer_size); + use_phys_exec = 0; } /* diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index c1af9fc65..455dcd29e 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -165,7 +165,8 @@ poll_thread(void *arg) if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { - poll_card->rx(poll_card->priv, (uint8_t *)qp->data, qp->len); + network_queue_put(poll_card->priv, (uint8_t *)qp->data, qp->len); + // poll_card->rx(poll_card->priv, (uint8_t *)qp->data, qp->len); data_valid = 1; } diff --git a/src/network/network.c b/src/network/network.c index e92f6dd09..93957b60c 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -57,6 +57,7 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/timer.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/network.h> @@ -118,6 +119,8 @@ int nic_do_log = ENABLE_NIC_LOG; #endif static mutex_t *network_mutex; static uint8_t *network_mac; +pc_timer_t network_queue_timer; +netpkt_t *first_pkt = NULL, *last_pkt = NULL; static struct { @@ -215,6 +218,99 @@ network_init(void) } +void +network_queue_put(void *priv, uint8_t *data, int len) +{ + netpkt_t *temp; + + temp = (netpkt_t *) malloc(sizeof(netpkt_t)); + memset(temp, 0, sizeof(netpkt_t)); + temp->priv = priv; + temp->data = (uint8_t *) malloc(len); + memcpy(temp->data, data, len); + temp->len = len; + + if (last_pkt != NULL) + last_pkt->next = temp; + last_pkt = temp; + + if (first_pkt == NULL) + first_pkt = temp; +} + + +static void +network_queue_get(netpkt_t *pkt) +{ + pkt->priv = NULL; + pkt->data = NULL; + pkt->len = 0; + + if (first_pkt == NULL) + return; + + memcpy(pkt, first_pkt, sizeof(netpkt_t)); +} + + +static void +network_queue_advance(void) +{ + netpkt_t *temp; + + temp = first_pkt; + + if (temp == NULL) + return; + + first_pkt = temp->next; + if (temp->data != NULL) + free(temp->data); + free(temp); + + if (first_pkt == NULL) + last_pkt = NULL; +} + + +static void +network_queue_clear(void) +{ + netpkt_t *temp = first_pkt; + + if (temp == NULL) + return; + + do { + if (temp->data != NULL) + free(temp->data); + free(temp); + temp = temp->next; + } while (temp != NULL); + + first_pkt = last_pkt = NULL; +} + + +static void +network_queue(void *priv) +{ + netpkt_t pkt; + + network_busy(1); + + network_queue_get(&pkt); + if (pkt.len > 0) { + net_cards[network_card].rx(pkt.priv, pkt.data, pkt.len); + timer_on_auto(&network_queue_timer, 0.762939453125 * 2.0 * ((double) pkt.len)); + } else + timer_on_auto(&network_queue_timer, 0.762939453125 * 2.0); + network_queue_advance(); + + network_busy(0); +} + + /* * Attach a network card to the system. * @@ -250,6 +346,11 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST (void)net_slirp_reset(&net_cards[network_card], network_mac); break; } + + first_pkt = last_pkt = NULL; + timer_add(&network_queue_timer, network_queue, NULL, 0); + /* 10 mbps. */ + timer_on_auto(&network_queue_timer, 0.762939453125 * 2.0); } @@ -257,6 +358,8 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST void network_close(void) { + timer_stop(&network_queue_timer); + /* If already closed, do nothing. */ if (network_mutex == NULL) return; @@ -282,6 +385,7 @@ network_close(void) network_mac = NULL; /* Here is where we should clear the queue. */ + network_queue_clear(); network_log("NETWORK: closed.\n"); } diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 8bc8cbab6..e44694430 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -50,7 +50,7 @@ typedef struct { uint8_t uart_ctrl; uint8_t uart_status; - uint16_t codec_regs[64]; + uint16_t codec_regs[128]; uint32_t codec_ctrl; struct { @@ -357,7 +357,9 @@ static uint32_t es1371_inl(uint16_t port, void *p) case 0x14: ret = es1371->codec_ctrl & 0x00ff0000; - ret |= es1371->codec_regs[(es1371->codec_ctrl >> 16) & 0x3f]; + ret |= es1371->codec_regs[(es1371->codec_ctrl >> 16) & 0x7f]; + if (((es1371->codec_ctrl >> 16) & 0x7f) == 0x26) + ret |= 0x0f; ret |= CODEC_READY; break; @@ -589,9 +591,10 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p) es1371->codec_ctrl = val; if (!(val & CODEC_READ)) { -// audiopci_log("Write codec %02x %04x\n", (val >> 16) & 0x3f, val & 0xffff); - es1371->codec_regs[(val >> 16) & 0x3f] = val & 0xffff; - switch ((val >> 16) & 0x3f) +// audiopci_log("Write codec %02x %04x\n", (val >> 16) & 0x7f, val & 0xffff); + if ((((val >> 16) & 0x7f) != 0x7c) || (((val >> 16) & 0x7f) != 0x7e)) + es1371->codec_regs[(val >> 16) & 0x7f] = val & 0xffff; + switch ((val >> 16) & 0x7f) { case 0x02: /*Master volume*/ if (val & 0x8000) @@ -1315,7 +1318,11 @@ static void *es1371_init(const device_t *info) timer_add(&es1371->dac[1].timer, es1371_poll, es1371, 1); generate_es1371_filter(); - + + /* Return a CS4297A like VMWare does. */ + es1371->codec_regs[0x7c] = 0x4352; + es1371->codec_regs[0x7e] = 0x5910; + return es1371; } diff --git a/src/win/win_media_menu.c b/src/win/win_media_menu.c index cdd4b90ac..6ff7d06e6 100644 --- a/src/win/win_media_menu.c +++ b/src/win/win_media_menu.c @@ -406,9 +406,6 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam) & 0xff00) { case IDM_FLOPPY_IMAGE_NEW: - if (menus == NULL) - break; - NewFloppyDialogCreate(hwnd, id, 0); break; @@ -416,9 +413,6 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) wp = 1; /* FALLTHROUGH */ case IDM_FLOPPY_IMAGE_EXISTING: - if (menus == NULL) - break; - ret = file_dlg_w_st(hwnd, IDS_2109, floppyfns[id], 0); if (! ret) { floppy_mount(id, wopenfilestring, wp); @@ -426,16 +420,10 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_FLOPPY_EJECT: - if (menus == NULL) - break; - floppy_eject(id); break; case IDM_FLOPPY_EXPORT_TO_86F: - if (menus == NULL) - break; - ret = file_dlg_w_st(hwnd, IDS_2076, floppyfns[id], 1); if (! ret) { plat_pause(1); @@ -447,9 +435,6 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_CDROM_MUTE: - if (menus == NULL) - break; - cdrom[id].sound_on ^= 1; config_save(); media_menu_update_cdrom(id); @@ -457,23 +442,14 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_CDROM_EMPTY: - if (menus == NULL) - break; - cdrom_eject(id); break; case IDM_CDROM_RELOAD: - if (menus == NULL) - break; - cdrom_reload(id); break; case IDM_CDROM_IMAGE: - if (menus == NULL) - break; - if (!file_dlg_w_st(hwnd, IDS_2075, cdrom[id].image_path, 0)) { cdrom_mount(id, wopenfilestring); } @@ -487,9 +463,6 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) wp = 1; /* FALLTHROUGH */ case IDM_ZIP_IMAGE_EXISTING: - if (menus == NULL) - break; - ret = file_dlg_w_st(hwnd, IDS_2058, zip_drives[id].image_path, 0); if (! ret) zip_mount(id, wopenfilestring, wp); @@ -511,9 +484,6 @@ media_menu_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) wp = 1; /* FALLTHROUGH */ case IDM_MO_IMAGE_EXISTING: - if (menus == NULL) - break; - ret = file_dlg_w_st(hwnd, IDS_2116, mo_drives[id].image_path, 0); if (! ret) mo_mount(id, wopenfilestring, wp);