diff --git a/src/86box.h b/src/86box.h index 260b6976d..8baa0de37 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.34 2019/11/01 + * Version: @(#)86box.h 1.0.35 2019/11/19 * * Authors: Miran Grca, *f Fred N. van Kempen, @@ -30,8 +30,8 @@ #define EMU_NAME "86Box" #define EMU_NAME_W L"86Box" #ifdef RELEASE_BUILD -#define EMU_VERSION "2.06" -#define EMU_VERSION_W L"2.06" +#define EMU_VERSION "2.07" +#define EMU_VERSION_W L"2.07" #else #define EMU_VERSION "2.10" #define EMU_VERSION_W L"2.10" diff --git a/src/config.c b/src/config.c index 361458c16..51a5a70d6 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.63 2019/10/21 + * Version: @(#)config.c 1.0.64 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -837,13 +837,18 @@ load_hard_disks(void) max_tracks = 1023; break; - case HDD_BUS_ESDI: case HDD_BUS_XTA: max_spt = 63; max_hpc = 16; max_tracks = 1023; break; + case HDD_BUS_ESDI: + max_spt = 99; + max_hpc = 16; + max_tracks = 266305; + break; + case HDD_BUS_IDE: max_spt = 63; max_hpc = 16; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 28f5ef7ae..a9d1e8e59 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.63 2019/11/01 + * Version: @(#)hdc_ide.c 1.0.65 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -109,7 +109,7 @@ #define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd #define FEATURE_DISABLE_IRQ_SERVICE 0xde -#define IDE_TIME 20.0 / 3.0 +#define IDE_TIME 10.0 typedef struct { @@ -175,70 +175,72 @@ ide_get_drive(int ch) double ide_get_period(ide_t *ide, int size) { - double period = 10.0 / 3.0; + double period = (10.0 / 3.0); + /* We assume that 1 MB = 1000000 B in this case, so we have as + many B/us as there are MB/s because 1 s = 1000000 us. */ switch(ide->mdma_mode & 0x300) { case 0x000: /* PIO */ switch(ide->mdma_mode & 0xff) { case 0: - period = 10.0 / 3.0; + period = (10.0 / 3.0); break; case 1: - period = (period * 600.0) / 383.0; + period = (20.0 / 3.83); break; case 2: - period = 25.0 / 3.0; + period = (25.0 / 3.0); break; case 3: - period = 100.0 / 9.0; + period = (100.0 / 9.0); break; case 4: - period = 50.0 / 3.0; + period = (50.0 / 3.0); break; } break; case 0x100: /* Single Word DMA */ switch(ide->mdma_mode & 0xff) { case 0: - period = 25.0 / 12.0; + period = (25.0 / 12.0); break; case 1: - period = 25.0 / 6.0; + period = (25.0 / 6.0); break; case 2: - period = 25.0 / 3.0; + period = (25.0 / 3.0); break; } break; case 0x200: /* Multiword DMA */ switch(ide->mdma_mode & 0xff) { case 0: - period = 25.0 / 6.0; + period = (25.0 / 6.0); break; case 1: - period = 40.0 / 3.0; + period = (40.0 / 3.0); break; case 2: - period = 50.0 / 3.0; + period = (50.0 / 3.0); break; } break; case 0x300: /* Ultra DMA */ switch(ide->mdma_mode & 0xff) { case 0: - period = 50.0 / 3.0; + period = (50.0 / 3.0); break; case 1: period = 25.0; break; case 2: - period = 100.0 / 3.0; + period = (100.0 / 3.0); break; case 3: - period = 400.0 / 9.0; + period = (400.0 / 9.0); break; case 4: - period = 200.0 / 3.0; + period = (200.0 / 3.0); break; case 5: period = 100.0; @@ -247,9 +249,26 @@ ide_get_period(ide_t *ide, int size) break; } - period *= 1048576.0; /* period * MB - get bytes per second */ - period = ((double) size) / period; /* size / period to get seconds */ - return period * 1000000.0; /* return seconds * 1000000 to convert to us */ + period = (10.0 / 3.0); + + period = (1.0 / period); /* get us for 1 byte */ + return period * ((double) size); /* multiply by bytes to get period for the entire transfer */ +} + + +double +ide_atapi_get_period(uint8_t channel) +{ + ide_t *ide = ide_drives[channel]; + + ide_log("ide_atapi_get_period(%i)\n", channel); + + if (!ide) { + ide_log("Get period failed\n"); + return -1.0; + } + + return ide_get_period(ide, 1); } @@ -261,10 +280,10 @@ ide_irq_raise(ide_t *ide) /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - if (!(ide->fdisk & 2) && (ide_boards[ide->board]->irq != -1)) { + if (!(ide->fdisk & 2)) { if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); - else + else if (ide_boards[ide->board]->irq != -1) picint(1 << ide_boards[ide->board]->irq); } @@ -281,14 +300,39 @@ ide_irq_lower(ide_t *ide) /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - if ((ide_boards[ide->board]->irq != -1) && ide->irqstat) { + if (ide->irqstat) { if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - else + else if (ide_boards[ide->board]->irq != -1) picintc(1 << ide_boards[ide->board]->irq); } - ide->irqstat=0; + ide->irqstat = 0; +} + + +static void +ide_irq_update(ide_t *ide) +{ + if (!ide_boards[ide->board]) + return; + + /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ + + if (!(ide->fdisk & 2) && ide->irqstat) { + if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); + } else if (ide_boards[ide->board]->irq != -1) { + picintc(1 << ide_boards[ide->board]->irq); + picint(1 << ide_boards[ide->board]->irq); + } + } else if (ide->fdisk & 2) { + if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + else if (ide_boards[ide->board]->irq != -1) + picintc(1 << ide_boards[ide->board]->irq); + } } @@ -1156,18 +1200,9 @@ static void dev_reset(ide_t *ide) { ide_set_signature(ide); - ide->error = 1; /*No error detected*/ - if (ide->type == IDE_ATAPI) { - ide->sc->status = 0; - ide->sc->error = 1; - ide_irq_raise(ide); - if (ide->stop) - ide->stop(ide->sc); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - } + if ((ide->type == IDE_ATAPI) && ide->stop) + ide->stop(ide->sc); } @@ -1178,6 +1213,7 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) ide_t *ide, *ide_other; int ch; + uint8_t old; ch = dev->cur_dev; ide = ide_drives[ch]; @@ -1189,35 +1225,55 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) return; dev->diag = 0; - + if ((val & 4) && !(ide->fdisk & 4)) { /* Reset toggled from 0 to 1, initiate reset procedure. */ if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; ide_set_callback(ide->board, 0.0); - ide->atastat = BSY_STAT; - if (ide->type == IDE_ATAPI) - ide->sc->status = BSY_STAT; - dev_reset(ide); } else if (!(val & 4) && (ide->fdisk & 4)) { /* Reset toggled from 1 to 0. */ if (!(ch & 1)) { - /* Currently active device is 0, fire the timer. */ - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.4; - ide_set_callback(ide->board, 0.4); + /* Currently active device is 0, use the device 0 reset protocol. */ + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->error = 1; + } + + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + + /* Fire the timer. */ + dev->diag = 0; ide->reset = 1; + ide_set_callback(ide->board, 500 * IDE_TIME); } else { /* Currently active device is 1, simply reset the status and the active device. */ - ide->atastat = 0x50; - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT | DSC_STAT; + dev_reset(ide); ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->error = 1; + } dev->cur_dev &= ~1; } } + old = ide->fdisk; ide->fdisk = ide_other->fdisk = val; + if (!(val & 0x02) && (old & 0x02) && ide->irqstat) + ide_irq_update(ide); } @@ -1357,6 +1413,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF)|((val & 0xF) << 24); + + ide_irq_update(ide); return; case 0x7: /* Command register */ @@ -1494,18 +1552,32 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - ide->atastat = BSY_STAT; - dev_reset(ide); - if (!(ch & 1)) - dev_reset(ide_other); - dev->diag = 1; + dev->cur_dev &= ~1; + ide = ide_drives[ch & ~1]; + ide_other = ide_drives[ch | 1]; + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; if (ide->type == IDE_ATAPI) { ide->sc->status = BSY_STAT; - ide->sc->callback = 0.4; + ide->sc->error = 1; } - ide_set_callback(ide->board, 0.4); + + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + + /* Fire the timer. */ + dev->diag = 1; ide->reset = 1; + ide_set_callback(ide->board, 200 * IDE_TIME); return; case WIN_PIDENTIFY: /* Identify Packet Device */ @@ -1825,12 +1897,6 @@ ide_callback(void *priv) if (ide->reset) { ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - ide = ide_drives[ch & ~1]; - ide_other = ide_drives[ch | 1]; - - if (!dev->diag) - dev_reset(ide_other); - ide->atastat = DRDY_STAT | DSC_STAT; if (ide->type == IDE_ATAPI) ide->sc->status = DRDY_STAT | DSC_STAT; @@ -1845,13 +1911,8 @@ ide_callback(void *priv) dev->diag = 0; ide_irq_raise(ide); } - - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.0; - if (ide_other->type == IDE_ATAPI) - ide_other->sc->callback = 0.0; - ide_set_callback(ide->board, 0.0); ide->reset = 0; + ide_set_callback(ide->board, 0.0); return; } diff --git a/src/disk/hdc_ide.h b/src/disk/hdc_ide.h index b2f96807a..b1e172748 100644 --- a/src/disk/hdc_ide.h +++ b/src/disk/hdc_ide.h @@ -9,12 +9,12 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdd_ide.h 1.0.15 2018/10/31 + * Version: @(#)hdd_ide.h 1.0.16 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #ifndef EMU_IDE_H # define EMU_IDE_H @@ -130,6 +130,7 @@ extern void ide_pri_disable(void); extern void ide_sec_enable(void); extern void ide_sec_disable(void); +extern double ide_atapi_get_period(uint8_t channel); extern void ide_set_callback(uint8_t channel, double callback); extern void ide_padstr(char *str, const char *src, int len); diff --git a/src/disk/zip.c b/src/disk/zip.c index 2da62f4af..60c775810 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,11 +9,11 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.37 2018/11/02 + * Version: @(#)zip.c 1.0.38 2019/11/19 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2018,2019 Miran Grca. */ #include #include @@ -854,6 +854,26 @@ zip_update_request_length(zip_t *dev, int len, int block_len) } +static double +zip_bus_speed(zip_t *dev) +{ + double ret = -1.0; + + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return 0.0; + } else { + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; + } +} + + static void zip_command_common(zip_t *dev) { @@ -868,12 +888,8 @@ zip_command_common(zip_t *dev) if (dev->drv->bus_type == ZIP_BUS_SCSI) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return; - } else { - if (zip_current_mode(dev) == 2) - bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ - } + } else + bytes_per_second = zip_bus_speed(dev); period = 1000000.0 / bytes_per_second; dev->callback = period * (double) (dev->packet_len); diff --git a/src/disk/zip.h b/src/disk/zip.h index b36b7e6bd..02c355472 100644 --- a/src/disk/zip.h +++ b/src/disk/zip.h @@ -9,11 +9,11 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.h 1.0.9 2018/10/31 + * Version: @(#)zip.h 1.0.10 2019/11/19 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2018,2019 Miran Grca. */ #ifndef EMU_ZIP_H #define EMU_ZIP_H @@ -23,7 +23,7 @@ #define BUF_SIZE 32768 -#define ZIP_TIME 500.0 +#define ZIP_TIME 10.0 #define ZIP_SECTORS (96*2048) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index f456272a0..d9224686b 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,13 +10,13 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.17 2018/11/12 + * Version: @(#)fdd_86f.c 1.0.18 2019/11/08 * - * Authors: Fred N. van Kempen, - * Miran Grca, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 Fred N. van Kempen. * * 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 @@ -1140,10 +1140,8 @@ d86f_get_bit(int drive, int side) if (! surface_bit) dev->last_word[side] |= current_bit; else { - if (current_bit) { - /* Bit is 1 and is set to fuzzy, we randomly generate it. */ - dev->last_word[side] |= (random_generate() & 1); - } + /* Bit is either 0 or 1 and is set to fuzzy, we randomly generate it. */ + dev->last_word[side] |= (random_generate() & 1); } } else dev->last_word[side] |= current_bit; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 3bd7c6c8e..554b35b56 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -8,7 +8,7 @@ * * Implementation of the XT-style keyboard. * - * Version: @(#)keyboard_xt.c 1.0.17 2019/03/05 + * Version: @(#)keyboard_xt.c 1.0.18 2019/11/14 * * Authors: Sarah Walker, * Miran Grca, @@ -532,7 +532,7 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: if ((kbd->type <= 1) && (kbd->pb & 0x80)) - ret = kbd->pd; + ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00); else if (((kbd->type == 2) || (kbd->type == 3)) && (kbd->pb & 0x80)) ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */ else @@ -559,10 +559,10 @@ kbd_read(uint16_t port, void *priv) LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ #if defined(DEV_BRANCH) && defined(USE_LASERXT) if (kbd->type == 6) - ret = (mem_size == 512) ? 0x0d : 0x0c; + ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00); else #endif - ret = kbd->pd & 0x0f; + ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00); } } ret |= (ppispeakon ? 0x20 : 0); diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 377666611..6491d9e44 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -22,15 +22,12 @@ * PC200: CGA with some NMI stuff. But we don't need that as it's only * used for TV and LCD displays, and we're emulating a CRT. * + * PPC512/640: Portable with both CGA-compatible and MDA-compatible monitors. + * * TODO: This module is not complete yet: * - * PC1512: The BIOS assumes 512K RAM, because I cannot figure out how to - * read the status of the LK4 jumper on the mainboard, which is - * somehow linked to the bus gate array on the NDMACS line... - * - * PC1612: EGA mode does not seem to work in the PC1640; it works fine - * in alpha mode, but in highres ("ECD350") mode, it displays - * some semi-random junk. Video-memory pointer maybe? + * All models: The internal mouse controller does not work correctly with + * version 7.04 of the mouse driver. * * Version: @(#)m_amstrad.c 1.0.20 2019/03/09 * diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 4ff2476ae..c2730db1c 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -8,7 +8,7 @@ * * Implementation of 286 and 386SX machines. * - * Version: @(#)m_at_286_386sx.c 1.0.1 2019/11/01 + * Version: @(#)m_at_286_386sx.c 1.0.2 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -203,8 +203,6 @@ machine_at_award286_init(const machine_t *model) machine_at_scat_init(model, 0); - device_add(&ide_isa_device); - return ret; } diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index a9699ba5b..9c0f6e8a1 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -57,7 +57,8 @@ static uint8_t ps2_read(uint16_t port, void *p) return ps2_105; case 0x190: return ps2_190; - + +#ifdef FIXME case 0x322: temp = ps2_hd.status; break; @@ -65,6 +66,7 @@ static uint8_t ps2_read(uint16_t port, void *p) temp = ps2_hd.int_status; ps2_hd.int_status &= ~0x02; break; +#endif default: temp = 0xff; @@ -116,7 +118,8 @@ static void ps2_write(uint16_t port, uint8_t val, void *p) case 0x190: ps2_190 = val; break; - + +#ifdef FIXME case 0x322: ps2_hd.ctrl = val; if (val & 0x80) @@ -127,6 +130,7 @@ static void ps2_write(uint16_t port, uint8_t val, void *p) if (ps2_hd.attention) ps2_hd.status = 0x14; break; +#endif } } @@ -137,15 +141,17 @@ static void ps2board_init(void) io_sethandler(0x0094, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0102, 0x0004, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0190, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); +#ifdef FIXME io_sethandler(0x0320, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0322, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0324, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); +#endif device_add(&port_92_device); ps2_190 = 0; - ps2_uart = device_add_inst(&i8250_device, 1); + ps2_uart = device_add_inst(&ns16450_device, 1); lpt1_init(0x3bc); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5f173e3f4..eb4786c07 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.49 2019/11/01 + * Version: @(#)machine_table.c 1.0.50 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -86,7 +86,7 @@ const machine_t machines[] = { #endif { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) diff --git a/src/machine/machine_table_new.c b/src/machine/machine_table_new.c index 016f2fb8b..e598db7da 100644 --- a/src/machine/machine_table_new.c +++ b/src/machine/machine_table_new.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.49 2019/11/01 + * Version: @(#)machine_table.c 1.0.50 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -73,7 +73,7 @@ const machine_t machines[] = { #endif { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 60d2b07a4..5acc9c170 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -8,11 +8,11 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.9 2018/10/19 + * Version: @(#)net_pcap.c 1.0.10 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -185,7 +185,10 @@ poll_thread(void *arg) if (pcap == NULL) break; /* Wait for the next packet to arrive. */ - data = (uint8_t *)f_pcap_next((void *)pcap, &h); + if (network_get_wait()) + data = NULL; + else + data = (uint8_t *)f_pcap_next((void *)pcap, &h); if (data != NULL) { // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index ec7bb1b09..8b8304854 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -8,11 +8,11 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.8 2018/10/19 + * Version: @(#)net_slirp.c 1.0.9 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -148,7 +148,7 @@ poll_thread(void *arg) /* Wait for the next packet to arrive. */ data_valid = 0; - if (QueuePeek(slirpq) != 0) { + if (!network_get_wait() && (QueuePeek(slirpq) != 0)) { /* Grab a packet from the queue. */ // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/network.c b/src/network/network.c index 0db312a39..6cff7945d 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,11 +12,11 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.10 2018/11/18 + * Version: @(#)network.c 1.0.12 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -99,6 +99,7 @@ static netcard_t net_cards[] = { int network_type; int network_ndev; int network_card; +static volatile int net_wait = 0; char network_host[522]; netdev_t network_devs[32]; #ifdef ENABLE_NIC_LOG @@ -220,6 +221,8 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) net_cards[network_card].rx = rx; network_mac = mac; + network_set_wait(0); + /* Create the network events. */ poll_data.wake_poll_thread = thread_create_event(); poll_data.poll_complete = thread_create_event(); @@ -442,3 +445,24 @@ network_card_get_from_internal_name(char *s) return(-1); } + + +void +network_set_wait(int wait) +{ + network_wait(1); + net_wait = wait; + network_wait(0); +} + + +int +network_get_wait(void) +{ + int ret; + + network_wait(1); + ret = net_wait; + network_wait(0); + return ret; +} diff --git a/src/network/network.h b/src/network/network.h index bdd4beb54..feae064ee 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -8,11 +8,11 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.2 2018/03/15 + * Version: @(#)network.h 1.0.3 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -124,6 +124,9 @@ extern char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); extern const device_t *network_card_getdevice(int); +extern void network_set_wait(int wait); +extern int network_get_wait(void); + #ifdef __cplusplus } #endif diff --git a/src/nvr.c b/src/nvr.c index fe0cfd006..53376295f 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -8,7 +8,7 @@ * * Implement a generic NVRAM/CMOS/RTC device. * - * Version: @(#)nvr.c 1.0.18 2019/03/16 + * Version: @(#)nvr.c 1.0.19 2019/11/19 * * Authors: Fred N. van Kempen, , * David Hrdlička, @@ -156,7 +156,7 @@ onesec_timer(void *priv) nvr->onesec_cnt = 0; } - timer_advance_u64(&nvr->onesec_time, (10000ULL * TIMER_USEC)); + timer_advance_u64(&nvr->onesec_time, (uint64_t)(10000ULL * TIMER_USEC)); } diff --git a/src/nvr_at.c b/src/nvr_at.c index b023ca332..967f14018 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -189,7 +189,7 @@ * including the later update (DS12887A) which implemented a * "century" register to be compatible with Y2K. * - * Version: @(#)nvr_at.c 1.0.15 2019/03/16 + * Version: @(#)nvr_at.c 1.0.16 2019/11/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -292,6 +292,8 @@ typedef struct { uint8_t addr; + int16_t count, state; + uint64_t ecount, rtc_time; pc_timer_t update_timer, @@ -450,43 +452,29 @@ timer_update(void *priv) } -static double -timer_nvr_period(nvr_t *nvr) +static void +timer_load_count(nvr_t *nvr) { - double dusec = (double) TIMER_USEC; + int c = nvr->regs[RTC_REGA] & REGA_RS; + local_t *local = (local_t *) nvr->data; - switch (nvr->regs[RTC_REGA] & REGA_RS) { + if ((nvr->regs[RTC_REGA] & 0x70) != 0x20) { + local->state = 0; + return; + } + + local->state = 1; + + switch (c) { case 0: + local->state = 0; + break; + case 1: case 2: + local->count = 1 << (c + 6); + break; default: - return 0.0; - case 1: - case 8: - return 3906.25 * dusec; - case 2: - case 9: - return 7812.5 * dusec; - case 3: - return 122.070 * dusec; - case 4: - return 244.141 * dusec; - case 5: - return 488.281 * dusec; - case 6: - return 976.5625 * dusec; - case 7: - return 1953.125 * dusec; - case 10: - return 15625.0 * dusec; - case 11: - return 31250.0 * dusec; - case 12: - return 62500.0 * dusec; - case 13: - return 125000.0 * dusec; - case 14: - return 250000.0 * dusec; - case 15: - return 500000.0 * dusec; + local->count = 1 << (c - 1); + break; } } @@ -497,13 +485,16 @@ timer_intr(void *priv) nvr_t *nvr = (nvr_t *)priv; local_t *local = (local_t *)nvr->data; - if (nvr->regs[RTC_REGA] & REGA_RS) { - local->rtc_time = timer_nvr_period(nvr); - timer_advance_u64(&local->rtc_timer, (uint64_t) local->rtc_time); - } else { - local->rtc_time = 0ULL; + timer_advance_u64(&local->rtc_timer, RTCCONST); + + if (local->state == 1) { + local->count--; + if (local->count == 0) + timer_load_count(nvr); + else + return; + } else return; - } nvr->regs[RTC_REGC] |= REGC_PF; if (nvr->regs[RTC_REGB] & REGB_PIE) { @@ -536,20 +527,6 @@ timer_tick(nvr_t *nvr) } -static void -nvr_pie_start(nvr_t *nvr) -{ - local_t *local = (local_t *)nvr->data; - - local->rtc_time = 0ULL; - timer_disable(&local->rtc_timer); - if ((nvr->regs[RTC_REGA] & REGA_RS) && ((nvr->regs[RTC_REGA] & 0x70) == 0x20)) { - local->rtc_time = timer_nvr_period(nvr); - timer_set_delay_u64(&local->rtc_timer, local->rtc_time); - } -} - - /* Write to one of the NVR registers. */ static void nvr_write(uint16_t addr, uint8_t val, void *priv) @@ -566,7 +543,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) switch(local->addr) { case RTC_REGA: nvr->regs[RTC_REGA] = val; - nvr_pie_start(nvr); + timer_load_count(nvr); break; case RTC_REGB: @@ -704,8 +681,7 @@ nvr_at_speed_changed(void *priv) local_t *local = (local_t *) nvr->data; timer_disable(&local->rtc_timer); - if (local->rtc_time > 0ULL) - timer_set_delay_u64(&local->rtc_timer, local->rtc_time); + timer_set_delay_u64(&local->rtc_timer, RTCCONST); timer_disable(&local->update_timer); if (local->ecount > 0ULL) @@ -774,7 +750,10 @@ nvr_at_init(const device_t *info) /* Start the timers. */ timer_add(&local->update_timer, timer_update, nvr, 0); + timer_add(&local->rtc_timer, timer_intr, nvr, 0); + timer_load_count(nvr); + timer_set_delay_u64(&local->rtc_timer, RTCCONST); /* Set up the I/O handler for this device. */ io_sethandler(0x0070, 2, diff --git a/src/pci.c b/src/pci.c index 1e27becdf..05519cc2e 100644 --- a/src/pci.c +++ b/src/pci.c @@ -8,7 +8,7 @@ * * Implementation the PCI bus. * - * Version: @(#)pci.c 1.0.3 2019/10/30 + * Version: @(#)pci.c 1.0.4 2019/11/06 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -635,7 +635,7 @@ trc_write(uint16_t port, uint8_t val, void *priv) if (!(trc_reg & 4) && (val & 4)) trc_reset(val); - trc_reg = val & 0xfd; + trc_reg = val & 0xfb; } diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 846ef8ef7..045c78fa9 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)scsi_cdrom.c 1.0.71 2019/09/26 + * Version: @(#)scsi_cdrom.c 1.0.72 2019/11/19 * * Author: Miran Grca, * @@ -604,15 +604,19 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) static double scsi_cdrom_bus_speed(scsi_cdrom_t *dev) { + double ret = -1.0; + if (dev->drv->bus_type == CDROM_BUS_SCSI) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return 0.0; } else { - /* TODO: Get the actual selected speed from IDE. */ - if (scsi_cdrom_current_mode(dev) == 2) - return 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - return 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; } } @@ -663,7 +667,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case 0xb9: case 0xbe: if (dev->current_cdb[0] == 0x42) - dev->callback += 200.0 * CDROM_TIME; + dev->callback += 40.0; /* Account for seek time. */ bytes_per_second = 176.0 * 1024.0; bytes_per_second *= (double) dev->drv->cur_speed; diff --git a/src/scsi/scsi_cdrom.h b/src/scsi/scsi_cdrom.h index f83c6457c..1c8be1382 100644 --- a/src/scsi/scsi_cdrom.h +++ b/src/scsi/scsi_cdrom.h @@ -9,17 +9,17 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)scsi_cdrom.h 1.0.1 2018/10/17 + * Version: @(#)scsi_cdrom.h 1.0.2 2019/11/19 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2018,2019 Miran Grca. */ #ifndef EMU_SCSI_CDROM_H #define EMU_SCSI_CDROM_H -#define CDROM_TIME 500.0 +#define CDROM_TIME 10.0 #ifdef SCSI_DEVICE_H diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 65b680483..56af023a1 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -13,7 +13,7 @@ * To do: Identify the type of serial EEPROM used and its * interface. * - * Version: @(#)scsi_ncr53c8xx.c 1.0.17 2018/10/30 + * Version: @(#)scsi_ncr53c8xx.c 1.0.18 2019/11/19 * * Authors: Paul Brook (QEMU) * Artyom Tarasenko (QEMU) @@ -705,10 +705,12 @@ ncr53c8xx_add_msg_byte(ncr53c8xx_t *dev, uint8_t data) static void ncr53c8xx_timer_on(ncr53c8xx_t *dev, scsi_device_t *sd, double p) { - if (p <= 0) - timer_on_auto(&dev->timer, ((double) sd->buffer_length) * 0.1); /* Fast SCSI: 10000000 bytes per second */ - else - timer_on_auto(&dev->timer, p); + double period; + + /* Fast SCSI: 10000000 bytes per second */ + period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + + timer_on_auto(&dev->timer, period + 40.0); } @@ -1023,11 +1025,12 @@ again: /* If we receive an empty opcode increment the DSP by 4 bytes instead of 8 and execute the next opcode at that location */ dev->dsp += 4; - timer_on_auto(&dev->timer, 10.0); if (insn_processed < 100) goto again; - else + else { + timer_on_auto(&dev->timer, 10.0); return; + } } addr = read_dword(dev, dev->dsp + 4); ncr53c8xx_log("SCRIPTS dsp=%08x opcode %08x arg %08x\n", dev->dsp, insn, addr); @@ -1093,8 +1096,6 @@ again: dev->dfifo = dev->dbc & 0xff; dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); - timer_on_auto(&dev->timer, 40.0); - if (dev->dcntl & NCR_DCNTL_SSM) ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SSI); return; @@ -1363,8 +1364,6 @@ again: ncr53c8xx_log("%02X: Unknown command\n", (uint8_t) (insn >> 30)); } - timer_on_auto(&dev->timer, 40.0); - ncr53c8xx_log("instructions processed %i\n", insn_processed); if (insn_processed > 10000 && !dev->waiting) { /* Some windows drivers make the device spin waiting for a memory @@ -1393,6 +1392,8 @@ again: ncr53c8xx_log("NCR 810: SCRIPTS: Waiting\n"); } + timer_on_auto(&dev->timer, 40.0); + ncr53c8xx_log("SCRIPTS execution stopped\n"); } @@ -1419,8 +1420,6 @@ ncr53c8xx_callback(void *p) if (dev->sstop) timer_stop(&dev->timer); - else - timer_on_auto(&dev->timer, 10.0); } diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 9c40d5e89..799614fea 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the PC speaker. + * + * Version: @(#)snd_speaker.c 1.0.0 2019/11/11 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ #include #include #include @@ -23,20 +41,31 @@ void speaker_update(void) { int32_t val; + double timer2_count, amplitude; + + timer2_count = pit.l[2] ? ((double) pit.l[2]) : 65536.0; + amplitude = ((timer2_count / 64.0) * 10240.0) - 5120.0; + + if (amplitude > 5120.0) + amplitude = 5120.0; if (speaker_pos >= sound_pos_global) return; for (; speaker_pos < sound_pos_global; speaker_pos++) { if (speaker_gated && was_speaker_enable) { - if (!pit.m[2] || pit.m[2]==4) - val = speakval; + if ((pit.m[2] == 0) || (pit.m[2] == 4)) + val = (int32_t) amplitude; else if (pit.l[2] < 0x40) val = 0xa00; else val = speakon ? 0x1400 : 0; - } else - val = was_speaker_enable ? 0x1400 : 0; + } else { + if (pit.m[2] == 1) + val = was_speaker_enable ? (int32_t) amplitude : 0; + else + val = was_speaker_enable ? 0x1400 : 0; + } if (!speaker_enable) was_speaker_enable = 0; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index fac75e163..acda3edde 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA and Chips & Technologies SuperEGA * graphics cards. * - * Version: @(#)vid_ega.c 1.0.22 2019/10/03 + * Version: @(#)vid_ega.c 1.0.23 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -389,9 +389,13 @@ ega_poll(void *p) ega->displine <<= 1; ega->y_add <<= 1; - ega_render_overscan_left(ega); ega->render(ega); + + ega->x_add = (overscan_x >> 1); + ega_render_overscan_left(ega); ega_render_overscan_right(ega); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; + ega->displine++; ega->ma = old_ma; @@ -454,8 +458,10 @@ ega_poll(void *p) if (ega->vc == ega->split) { ega->ma = ega->maback = 0; ega->sc = 0; - if (ega->attrregs[0x10] & 0x20) + if (ega->attrregs[0x10] & 0x20) { ega->scrollcache = 0; + ega->x_add = (overscan_x >> 1); + } } if (ega->vc == ega->dispend) { ega->dispon = 0; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index e5bcc9fb0..cf5ec7d50 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -8,7 +8,7 @@ * * EGA renderers. * - * Version: @(#)vid_ega_render.c 1.0.6 2019/10/03 + * Version: @(#)vid_ega_render.c 1.0.7 2019/11/19 * * Author: Sarah Walker, * Miran Grca, @@ -53,7 +53,7 @@ ega_render_blank(ega_t *ega) if ((ega->displine + ega->y_add) < 0) return; - for (x = 0; x < ega->hdisp; x++) { + for (x = 0; x < (ega->hdisp + ega->scrollcache); x++) { switch (ega->seqregs[1] & 9) { case 0: for (xx = 0; xx < 9; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0; @@ -120,7 +120,7 @@ ega_render_text_40(ega_t *ega) p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < ega->hdisp; x += xinc) { + for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); chr = ega->vram[(ega->ma << 1) & ega->vrammask]; attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; @@ -183,7 +183,7 @@ ega_render_text_80(ega_t *ega) p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < ega->hdisp; x += xinc) { + for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); chr = ega->vram[(ega->ma << 1) & ega->vrammask]; attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; @@ -240,7 +240,7 @@ ega_render_2bpp_lowres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 16) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { addr = ega->ma; if (!(ega->crtc[0x17] & 0x40)) { @@ -299,7 +299,7 @@ ega_render_2bpp_highres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 8) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { addr = ega->ma; if (!(ega->crtc[0x17] & 0x40)) { @@ -358,7 +358,7 @@ ega_render_4bpp_lowres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 16) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { addr = ega->ma; oddeven = 0; @@ -431,7 +431,7 @@ ega_render_4bpp_highres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 8) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { addr = ega->ma; oddeven = 0; diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index 0f276a103..0a8ca6e6c 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -38,7 +38,7 @@ * This is implemented by holding a FIFO of unlimited depth in * the IM1024 to receive the data. * - * Version: @(#)vid_im1024.c 1.0.3 2019/03/03 + * Version: @(#)vid_im1024.c 1.0.4 2019/11/04 * * Authors: Fred N. van Kempen, * John Elliott, @@ -1008,13 +1008,6 @@ im1024_speed_changed(void *priv) } -static const device_config_t im1024_config[] = { - { - "", "", -1 - } -}; - - const device_t im1024_device = { "ImageManager 1024", DEVICE_ISA, 0, @@ -1022,5 +1015,5 @@ const device_t im1024_device = { im1024_available, im1024_speed_changed, NULL, - im1024_config + NULL }; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 637709c1a..e8ccbee4b 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -44,7 +44,7 @@ * * This is expected to be done shortly. * - * Version: @(#)vid_pgc.c 1.0.3 2019/09/28 + * Version: @(#)vid_pgc.c 1.0.5 2019/11/04 * * Authors: Fred N. van Kempen, * John Elliott, @@ -2311,7 +2311,7 @@ pgc_cga_text(pgc_t *dev, int w) uint32_t val; int cw = (w == 80) ? 8 : 16; - addr = &dev->cga_vram[(((ma << 1) + ((dev->displine / pitch)*w)) * 2) & 0x3ffe]; + addr = &dev->cga_vram[((ma + ((dev->displine / pitch) * w)) * 2) & 0x3ffe]; ma += (dev->displine / pitch) * w; for (x = 0; x < w; x++) { @@ -2698,13 +2698,6 @@ pgc_standalone_init(const device_t *info) } -static const device_config_t pgc_config[] = { - { - "", "", -1 - } -}; - - const device_t pgc_device = { "PGC", DEVICE_ISA, 0, @@ -2714,5 +2707,5 @@ const device_t pgc_device = { NULL, pgc_speed_changed, NULL, - pgc_config + NULL }; diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 39d314ea8..3ad4a2a54 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -8,7 +8,7 @@ * * Sigma Color 400 emulation. * - * Version: @(#)vid_sigma.c 1.0.4 2019/05/23 + * Version: @(#)vid_sigma.c 1.0.5 2019/11/08 * * Authors: John Elliott, * @@ -422,7 +422,7 @@ static void sigma_text80(sigma_t *sigma) uint16_t ma = ((sigma->ma << 1) & 0x3FFF); int drawcursor; uint32_t cols[4]; - uint8_t *vram = sigma->vram + ((ma << 1) % 4000); + uint8_t *vram = sigma->vram + (ma & 0x3FFF); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) @@ -475,10 +475,10 @@ sigma_text40(sigma_t *sigma) int x, c; uint8_t chr, attr; uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); - uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + uint16_t ma = ((sigma->ma << 1) & 0x3FFF); int drawcursor; uint32_t cols[4]; - uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); + uint8_t *vram = sigma->vram + (ma & 0x3FFF); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index c3c31ef59..d2f7e45a3 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.37 2019/10/21 + * Version: @(#)vid_svga.c 1.0.38 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -530,10 +530,13 @@ svga_recalctimings(svga_t *svga) overscan_y = 16; } - overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; - if (svga->seqregs[1] & 8) - overscan_x <<= 1; + if (svga->seqregs[1] & 8) + overscan_x <<= 1; + } else + overscan_x = 16; if (svga->recalctimings_ex) svga->recalctimings_ex(svga); @@ -553,6 +556,7 @@ svga_recalctimings(svga_t *svga) disptime *= 2; _dispontime *= 2; } + _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; _dispofftime *= crtcconst; @@ -572,6 +576,7 @@ svga_poll(void *p) svga_t *svga = (svga_t *)p; uint32_t x, blink_delay; int wx, wy; + int skip = (svga->crtc[8] >> 5) & 0x03; if (!svga->linepos) { if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { @@ -625,9 +630,12 @@ svga_poll(void *p) } if (!svga->override) { - svga_render_overscan_left(svga); svga->render(svga); + + svga->x_add = (overscan_x >> 1); + svga_render_overscan_left(svga); svga_render_overscan_right(svga); + svga->x_add = (overscan_x >> 1) - svga->scrollcache; } if (svga->overlay_on) { @@ -702,8 +710,10 @@ svga_poll(void *p) if (svga->vc == svga->split) { svga->ma = svga->maback = 0; svga->sc = 0; - if (svga->attrregs[0x10] & 0x20) + if (svga->attrregs[0x10] & 0x20) { svga->scrollcache = 0; + svga->x_add = (overscan_x >> 1); + } } if (svga->vc == svga->dispend) { if (svga->vblank_start) @@ -761,9 +771,9 @@ svga_poll(void *p) svga->ma = svga->maback = svga->ma_latch; svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf]; - svga->ma <<= 2; - svga->maback <<= 2; - svga->ca <<= 2; + svga->ma = (svga->ma << 2) + (skip << 2); + svga->maback = (svga->maback << 2) + (skip << 2); + svga->ca = (svga->ca << 2) + (skip << 2); } if (svga->vc == svga->vtotal) { svga->vc = 0; @@ -786,7 +796,7 @@ svga_poll(void *p) else svga->scrollcache = (svga->scrollcache & 0x06) >> 1; - if (svga->seqregs[1] & 8) + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) svga->scrollcache <<= 1; svga->x_add = (overscan_x >> 1) - svga->scrollcache; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 04a1f7219..2448bd1fb 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -8,7 +8,7 @@ * * SVGA renderers. * - * Version: @(#)vid_svga_render.c 1.0.13 2019/03/08 + * Version: @(#)vid_svga_render.c 1.0.14 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -40,7 +40,7 @@ svga_render_blank(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x < svga->hdisp; x++) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x++) { switch (svga->seqregs[1] & 9) { case 0: for (xx = 0; xx < 9; xx++) @@ -84,7 +84,7 @@ svga_render_overscan_right(svga_t *svga) if (svga->scrblank || (svga->hdisp == 0)) return; - right = (overscan_x >> 1) + svga->scrollcache; + right = (overscan_x >> 1); for (i = 0; i < right; i++) buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp + i] = svga->overscan_color; } @@ -111,7 +111,7 @@ svga_render_text_40(svga_t *svga) p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < svga->hdisp; x += xinc) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; @@ -174,7 +174,7 @@ svga_render_text_80(svga_t *svga) p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < svga->hdisp; x += xinc) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; @@ -237,7 +237,7 @@ svga_render_text_80_ksc5601(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < svga->hdisp; x += xinc) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; @@ -348,7 +348,7 @@ svga_render_2bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 16) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { addr = svga->ma; if (!(svga->crtc[0x17] & 0x40)) { @@ -411,7 +411,7 @@ svga_render_2bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { addr = svga->ma; if (!(svga->crtc[0x17] & 0x40)) { @@ -473,7 +473,7 @@ svga_render_4bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 16) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { addr = svga->ma; oddeven = 0; @@ -547,7 +547,7 @@ svga_render_4bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { addr = svga->ma; oddeven = 0; @@ -617,7 +617,7 @@ svga_render_8bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = p[1] = svga->map8[dat & 0xff]; @@ -650,7 +650,7 @@ svga_render_8bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = svga->map8[dat & 0xff]; p[1] = svga->map8[(dat >> 8) & 0xff]; @@ -688,7 +688,7 @@ svga_render_15bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; @@ -724,7 +724,7 @@ svga_render_15bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_15to32[dat & 0xffff]; p[x + 1] = video_15to32[dat >> 16]; @@ -764,7 +764,7 @@ svga_render_15bpp_mix_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; @@ -800,7 +800,7 @@ svga_render_15bpp_mix_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; dat >>= 16; @@ -844,7 +844,7 @@ svga_render_16bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; @@ -875,7 +875,7 @@ svga_render_16bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; @@ -912,7 +912,7 @@ svga_render_24bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; svga->ma &= svga->vram_display_mask; @@ -940,7 +940,7 @@ svga_render_24bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[x] = dat & 0xffffff; @@ -974,7 +974,7 @@ svga_render_32bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -1002,7 +1002,7 @@ svga_render_32bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = dat & 0xffffff; } @@ -1029,7 +1029,7 @@ svga_render_ABGR8888_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } @@ -1056,7 +1056,7 @@ svga_render_RGBA8888_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = dat >> 8; } diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 49c941934..d28c34767 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)86Box.rc 1.0.53 2019/11/01 + * Version: @(#)86Box.rc 1.0.54 2019/11/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -225,7 +225,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,129,94,71,12 ICON 100,IDC_ABOUT_ICON,7,7,20,20 #ifdef RELEASE_BUILD - LTEXT "86Box v2.06 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + LTEXT "86Box v2.07 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", IDC_ABOUT_ICON,54,7,146,73 #else LTEXT "86Box v2.10 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", @@ -980,8 +980,8 @@ END VS_VERSION_INFO VERSIONINFO #ifdef RELEASE_BUILD - FILEVERSION 2,6,0,0 - PRODUCTVERSION 2,6,0,0 + FILEVERSION 2,7,0,0 + PRODUCTVERSION 2,7,0,0 #else FILEVERSION 2,10,0,0 PRODUCTVERSION 2,10,0,0 @@ -1004,7 +1004,7 @@ BEGIN VALUE "CompanyName", "IRC #SoftHistory\0" VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" #ifdef RELEASE_BUILD - VALUE "FileVersion", "2.06\0" + VALUE "FileVersion", "2.07\0" #else VALUE "FileVersion", "2.10\0" #endif @@ -1015,7 +1015,7 @@ BEGIN VALUE "PrivateBuild", "\0" VALUE "ProductName", "86Box Emulator\0" #ifdef RELEASE_BUILD - VALUE "ProductVersion", "2.06\0" + VALUE "ProductVersion", "2.07\0" #else VALUE "ProductVersion", "2.10\0" #endif diff --git a/src/win/win.c b/src/win/win.c index ac91ac436..f4481feed 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.58 2019/10/19 + * Version: @(#)win.c 1.0.59 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -197,11 +197,6 @@ set_language(int id) /* Load the strings table for this ID. */ LoadCommonStrings(); - -#if 0 - /* Update the menus for this ID. */ - MenuUpdate(); -#endif } } @@ -381,6 +376,10 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) if (! pc_init(argc, argw)) { /* Detach from console. */ CreateConsole(0); + + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); + return(1); } @@ -428,6 +427,9 @@ do_stop(void) plat_delay_ms(100); + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); + pc_close(thMain); thMain = NULL; @@ -627,7 +629,6 @@ plat_dir_check(wchar_t *path) int plat_dir_create(wchar_t *path) { - // return((int)CreateDirectory(path, NULL)); return((int)SHCreateDirectory(hwndMain, path)); } @@ -696,10 +697,6 @@ plat_vidapi_name(int api) break; case 2: -#if 0 - /* Direct3D is default. */ - name = "d3d"; -#endif break; case 3: @@ -707,10 +704,6 @@ plat_vidapi_name(int api) break; #else case 1: -#if 0 - /* Direct3D is default. */ - name = "d3d"; -#endif break; case 2: diff --git a/src/win/win.h b/src/win/win.h index 747c8c616..05ce73978 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.26 2019/11/01 + * Version: @(#)win.h 1.0.28 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -43,7 +43,12 @@ #define SB_MENU_NAME L"StatusBarMenu" #define FS_CLASS_NAME L"86BoxFullScreen" -/* Application-specific window messages. */ +/* Application-specific window messages. + + A dialog sends 0x8895 with WPARAM = 1 followed by 0x8896 with WPARAM = 1 on open, + and 0x8895 with WPARAM = followed by 0x8896 with WPARAM = 0. + + All shutdowns will send an 0x8897. */ #define WM_RESETD3D WM_USER #define WM_LEAVEFULLSCREEN WM_USER+1 #define WM_SAVESETTINGS 0x8888 @@ -55,10 +60,10 @@ #define WM_CTRLALTDEL 0x8894 /* Pause/resume status: WPARAM = 1 for paused, 0 for resumed. */ #define WM_SENDSTATUS 0x8895 -/* Settings status: WPARAM = 1 for open, 0 for closed. */ -#define WM_SENDSSTATUS 0x8896 -/* Emulator shut down. */ -#define WM_SHUTDOWN_DONE 0x8897 +/* Dialog (Settings or message box) status: WPARAM = 1 for open, 0 for closed. */ +#define WM_SENDDLGSTATUS 0x8896 +/* The emulator has shut down. */ +#define WM_HAS_SHUTDOWN 0x8897 #ifdef USE_VNC #ifdef USE_D2D @@ -118,6 +123,9 @@ extern void win_mouse_close(void); extern void win_mouse_handle(LPARAM lParam, int infocus); #endif +extern void win_notify_dlg_open(void); +extern void win_notify_dlg_closed(void); + extern LPARAM win_get_string(int id); extern intptr_t fdd_type_to_icon(int type); diff --git a/src/win/win_d3d.cpp b/src/win/win_d3d.cpp index 974b17341..cb5942ab7 100644 --- a/src/win/win_d3d.cpp +++ b/src/win/win_d3d.cpp @@ -8,7 +8,7 @@ * * Rendering module for Microsoft Direct3D 9. * - * Version: @(#)win_d3d.cpp 1.0.13 2019/10/12 + * Version: @(#)win_d3d.cpp 1.0.14 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -43,8 +43,8 @@ static LPDIRECT3DTEXTURE9 d3dTexture = NULL; static D3DPRESENT_PARAMETERS d3dpp; static HWND d3d_hwnd; static HWND d3d_device_window; -static int d3d_w, - d3d_h; +static int d3d_w, d3d_h; +static int d3d_fs; static volatile int d3d_enabled = 0; static CUSTOMVERTEX d3d_verts[] = { @@ -143,17 +143,15 @@ d3d_size(RECT w_rect, double *l, double *t, double *r, double *b, int w, int h) static void -d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) +d3d_blit(int x, int y, int y1, int y2, int w, int h) { -#if 0 HRESULT hr = D3D_OK; HRESULT hbsr = D3D_OK; VOID* pVoid; D3DLOCKED_RECT dr; - RECT w_rect; + RECT r; int yy; - double l = 0, t = 0, r = 0, b = 0; - RECT lock_rect; + double l = 0, t = 0, rr = 0, b = 0; /* FS_ONLY */ if (!d3d_enabled) { video_blit_complete(); @@ -165,19 +163,21 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) return; /*Nothing to do*/ } - lock_rect.top = y1; - lock_rect.left = 0; - lock_rect.bottom = y2; - lock_rect.right = 2047; + r.top = y1; + r.left = 0; + r.bottom = y2; + r.right = 2047; - hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); - if (hr == D3D_OK) { + hr = d3dTexture->LockRect(0, &dr, &r, 0); + if (hr == D3D_OK) { for (yy = y1; yy < y2; yy++) { if (buffer32) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); - else - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); + else + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); + } } } @@ -188,8 +188,8 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) return; } - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = @@ -197,32 +197,35 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - GetClientRect(d3d_device_window, &w_rect); - d3d_size(w_rect, &l, &t, &r, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = r; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = r; - d3d_verts[4].y = t; - d3d_verts[5].x = r; - d3d_verts[5].y = b; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; + if (d3d_fs) { + GetClientRect(d3d_device_window, &r); + d3d_size(r, &l, &t, &rr, &b, w, h); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = l; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = t; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = rr; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = b; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = rr - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = rr - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; + } else { + GetClientRect(d3d_hwnd, &r); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right-r.left)-0.5; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom-r.top)-0.5; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right-r.left)-40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right-r.left)-8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; + } if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer if (hr == D3D_OK) - hr = v_buffer->Unlock(); + hr = v_buffer->Unlock(); // unlock the vertex buffer if (hr == D3D_OK) hbsr = hr = d3ddev->BeginScene(); @@ -253,217 +256,6 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) if (hr == D3D_OK) hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(hwndMain, WM_RESETD3D, 0, 0); -#else - HRESULT hr = D3D_OK; - HRESULT hbsr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r, w_rect; - int yy; - double l = 0, t = 0, rr = 0, b = 0; - - if (!d3d_enabled) { - video_blit_complete(); - return; - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - hr = d3dTexture->LockRect(0, &dr, &r, 0); - if (hr == D3D_OK) { - for (yy = y1; yy < y2; yy++) { - if (buffer32) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); - else - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); - } - } - } - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } else { - video_blit_complete(); - return; - } - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - GetClientRect(d3d_device_window, &w_rect); - d3d_size(w_rect, &l, &t, &rr, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = rr; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = rr; - d3d_verts[4].y = t; - d3d_verts[5].x = rr; - d3d_verts[5].y = b; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = rr - 40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = rr - 8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) - hbsr = hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) { - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - } - - if (hbsr == D3D_OK) - hr = d3ddev->EndScene(); - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); -#endif -} - - -static void -d3d_blit(int x, int y, int y1, int y2, int w, int h) -{ - HRESULT hr = D3D_OK; - HRESULT hbsr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r; - int yy; - - if (!d3d_enabled) { - video_blit_complete(); - return; - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - hr = d3dTexture->LockRect(0, &dr, &r, 0); - if (hr == D3D_OK) { - for (yy = y1; yy < y2; yy++) { - if (buffer32) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); - else - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); - } - } - } - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } else { - video_blit_complete(); - return; - } - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - GetClientRect(d3d_hwnd, &r); - d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; - d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; - d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right-r.left)-0.5; - d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom-r.top)-0.5; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right-r.left)-40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right-r.left)-8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) - hbsr = hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) { - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - } - - if (hbsr == D3D_OK) - hr = d3ddev->EndScene(); - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); } @@ -557,6 +349,7 @@ d3d_init(HWND h) video_setblit(d3d_blit); + d3d_fs = 0; d3d_enabled = 1; return(1); @@ -629,8 +422,9 @@ d3d_init_fs(HWND h) mouse_capture = 1; - video_setblit(d3d_blit_fs); + video_setblit(d3d_blit); + d3d_fs = 1; d3d_enabled = 1; return(1); diff --git a/src/win/win_ddraw.cpp b/src/win/win_ddraw.cpp index 35772613c..f7f97ff35 100644 --- a/src/win/win_ddraw.cpp +++ b/src/win/win_ddraw.cpp @@ -11,7 +11,7 @@ * NOTES: This code should be re-merged into a single init() with a * 'fullscreen' argument, indicating FS mode is requested. * - * Version: @(#)win_ddraw.cpp 1.0.15 2019/10/12 + * Version: @(#)win_ddraw.cpp 1.0.16 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -48,6 +48,7 @@ static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; static int ddraw_w, ddraw_h; +static int ddraw_fs; static volatile int ddraw_enabled = 0; @@ -148,97 +149,17 @@ ddraw_fs_size(RECT w_rect, RECT *r_dest, int w, int h) } -static void -ddraw_blit_fs(int x, int y, int y1, int y2, int w, int h) -{ - RECT r_src; - RECT r_dest; - RECT w_rect; - int yy; - HRESULT hr; - DDBLTFX ddbltfx; - - if (!ddraw_enabled) { - video_blit_complete(); - return; - } - - if (lpdds_back == NULL) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, - DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, - DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (! ddsd.lpSurface) { - video_blit_complete(); - return; - } - - for (yy = y1; yy < y2; yy++) { - if (buffer32) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(buffer32->line[y + yy][x]), w); - else - memcpy((void *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(buffer32->line[y + yy][x]), w * 4); - } - } - video_blit_complete(); - lpdds_back->Unlock(NULL); - - w_rect.left = 0; - w_rect.top = 0; - w_rect.right = ddraw_w; - w_rect.bottom = ddraw_h; - ddraw_fs_size(w_rect, &r_dest, w, h); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwFillColor = 0; - - lpdds_back2->Blt(&w_rect, NULL, NULL, - DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - - hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); - if (hr == DDERR_SURFACELOST) { - lpdds_pri->Restore(); - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); - } -} - - static void ddraw_blit(int x, int y, int y1, int y2, int w, int h) { RECT r_src; RECT r_dest; POINT po; - HRESULT hr; + RECT w_rect; int yy; + HRESULT hr; + DDBLTFX ddbltfx; + RECT *r_tgt = ddraw_fs ? &r_dest : &r_src; if (!ddraw_enabled) { video_blit_complete(); @@ -286,29 +207,53 @@ ddraw_blit(int x, int y, int y1, int y2, int w, int h) video_blit_complete(); lpdds_back->Unlock(NULL); - po.x = po.y = 0; - - ClientToScreen(ddraw_hwnd, &po); - GetClientRect(ddraw_hwnd, &r_dest); - OffsetRect(&r_dest, po.x, po.y); - + if (ddraw_fs) { + w_rect.left = 0; + w_rect.top = 0; + w_rect.right = ddraw_w; + w_rect.bottom = ddraw_h; + ddraw_fs_size(w_rect, &r_dest, w, h); + } else { + po.x = po.y = 0; + + ClientToScreen(ddraw_hwnd, &po); + GetClientRect(ddraw_hwnd, &r_dest); + OffsetRect(&r_dest, po.x, po.y); + } + r_src.left = 0; r_src.top = 0; r_src.right = w; r_src.bottom = h; - hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (ddraw_fs) { + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = 0; + + lpdds_back2->Blt(&w_rect, NULL, NULL, + DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + } + + hr = lpdds_back2->Blt(r_tgt, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_back2->Restore(); + lpdds_back2->Blt(r_tgt, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + if (ddraw_fs) + hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); + else { + lpdds_back2->Unlock(NULL); + + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); } - lpdds_back2->Unlock(NULL); - - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); if (hr == DDERR_SURFACELOST) { lpdds_pri->Restore(); - lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + if (ddraw_fs) + lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); + else + lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); } } @@ -373,6 +318,7 @@ ddraw_init(HWND h) video_setblit(ddraw_blit); + ddraw_fs = 0; ddraw_enabled = 1; return(1); @@ -429,8 +375,9 @@ ddraw_init_fs(HWND h) ddraw_hwnd = h; - video_setblit(ddraw_blit_fs); + video_setblit(ddraw_blit); + ddraw_fs = 1; ddraw_enabled = 1; return(1); diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index b6d4e5f64..0dff080c9 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -8,7 +8,7 @@ * * Handle the New Floppy Image dialog. * - * Version: @(#)win_new_floppy.c 1.0.12 2019/10/22 + * Version: @(#)win_new_floppy.c 1.0.13 2019/11/19 * * Authors: Miran Grca, * @@ -302,6 +302,7 @@ create_zip_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_zdi, uint16_t base = 0x1000; uint32_t pbar_max = 0; uint32_t i; + MSG msg; f = plat_fopen(file_name, L"wb"); if (!f) @@ -496,6 +497,11 @@ create_zip_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_zdi, for (i = 0; i < pbar_max; i++) { fwrite(&empty[i << 11], 1, 2048, f); SendMessage(h, PBM_SETPOS, (WPARAM) i + 2, (LPARAM) 0); + + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } free(empty); diff --git a/src/win/win_settings.c b/src/win/win_settings.c index ab5a5baa8..ed6747d5a 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.57 2019/11/01 + * Version: @(#)win_settings.c 1.0.62 2019/11/19 * * Authors: Miran Grca, * David Hrdlička, @@ -2515,6 +2515,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM uint8_t id = 0; wchar_t *twcs; vhd_footer_t *vft = NULL; + MSG msg; switch (message) { case WM_INITDIALOG: @@ -2672,7 +2673,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ } - memset(buf, 0, 512); + big_buf = (char *) malloc(1048576); + memset(big_buf, 0, 1048576); temp_size = size; @@ -2703,19 +2705,23 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM ShowWindow(h, SW_SHOW); } + h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); + if (size) { - fwrite(buf, 1, size, f); + fwrite(big_buf, 1, size, f); SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); } if (r) { - big_buf = (char *) malloc(1048576); - memset(big_buf, 0, 1048576); for (i = 0; i < r; i++) { fwrite(big_buf, 1, 1048576, f); SendMessage(h, PBM_SETPOS, (WPARAM) (size + 1), (LPARAM) 0); + + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } - free(big_buf); } if (image_is_vhd(hd_file_name, 0)) { @@ -2727,14 +2733,14 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM vft->geom.heads = hpc; vft->geom.spt = spt; generate_vhd_checksum(vft); - memset(buf, 0, 512); - vhd_footer_to_bytes((uint8_t *) buf, vft); - fwrite(buf, 1, 512, f); - memset(buf, 0, 512); + vhd_footer_to_bytes((uint8_t *) big_buf, vft); + fwrite(big_buf, 1, 512, f); free(vft); vft = NULL; } + free(big_buf); + fclose(f); settings_msgbox(MBX_INFO, (wchar_t *)IDS_4113); } @@ -3055,16 +3061,16 @@ hdd_add_file_open_error: max_hpc = 15; max_tracks = 1023; break; - case HDD_BUS_ESDI: - max_spt = 43; /* ESDI drives usually had 32 to 43 sectors per track. */ - max_hpc = 16; - max_tracks = 266305; - break; case HDD_BUS_XTA: max_spt = 63; max_hpc = 16; max_tracks = 1023; break; + case HDD_BUS_ESDI: + max_spt = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ + max_hpc = 16; + max_tracks = 266305; + break; case HDD_BUS_IDE: max_spt = 63; max_hpc = 255; @@ -4477,14 +4483,6 @@ win_settings_main_insert_categories(HWND hwndList) -static void -win_settings_communicate_closure(void) -{ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSSTATUS, (WPARAM) 0, (LPARAM) hwndMain); -} - - #if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else @@ -4502,8 +4500,7 @@ win_settings_confirm(HWND hdlg, int button) DestroyWindow(hwndChildDialog); EndDialog(hdlg, 0); - plat_pause(0); - win_settings_communicate_closure(); + win_notify_dlg_closed(); return button ? TRUE : FALSE; } else @@ -4555,8 +4552,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case IDCANCEL: DestroyWindow(hwndChildDialog); EndDialog(hdlg, 0); - plat_pause(0); - win_settings_communicate_closure(); + win_notify_dlg_closed(); return TRUE; } break; @@ -4571,10 +4567,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) void win_settings_open_ex(HWND hwnd, int category) { - plat_pause(1); - - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSSTATUS, (WPARAM) 1, (LPARAM) hwndMain); + win_notify_dlg_open(); first_cat = category; DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index a23d74361..312a76826 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.41 2019/11/01 + * Version: @(#)win_ui.c 1.0.44 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -64,8 +64,8 @@ WCHAR wopenfilestring[260]; /* Local data. */ static wchar_t wTitle[512]; static HHOOK hKeyboardHook; -static int hook_enabled = 0; -static int save_window_pos = 0; +static int hook_enabled = 0, manager_wm = 0; +static int save_window_pos = 0, pause_state = 0; static int vis = -1; @@ -270,6 +270,27 @@ LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) } +void +win_notify_dlg_open(void) +{ + manager_wm = 1; + pause_state = dopause; + plat_pause(1); + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 1, (LPARAM) hwndMain); +} + + +void +win_notify_dlg_closed(void) +{ + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 0, (LPARAM) hwndMain); + plat_pause(pause_state); + manager_wm = 0; +} + + static LRESULT CALLBACK MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -297,9 +318,11 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_ACTION_HRESET: + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); if (i == 0) pc_reset(1); + win_notify_dlg_closed(); break; case IDM_ACTION_RESET_CAD: @@ -307,14 +330,14 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_ACTION_EXIT: + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); } + win_notify_dlg_closed(); break; case IDM_ACTION_CTRL_ALT_ESC: @@ -671,52 +694,68 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return(0); case WM_CLOSE: + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); } + win_notify_dlg_closed(); break; case WM_DESTROY: - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); break; case WM_SHOWSETTINGS: + if (manager_wm) + break; + manager_wm = 1; win_settings_open(hwnd); + manager_wm = 0; break; case WM_PAUSE: + if (manager_wm) + break; + manager_wm = 1; plat_pause(dopause ^ 1); CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); + manager_wm = 0; break; case WM_HARDRESET: + if (manager_wm) + break; + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); if (i == 0) pc_reset(1); + win_notify_dlg_closed(); break; case WM_SHUTDOWN: + if (manager_wm) + break; + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); } + win_notify_dlg_closed(); break; case WM_CTRLALTDEL: + if (manager_wm) + break; + manager_wm = 1; pc_reset(0); + manager_wm = 0; break; case WM_SYSCOMMAND: @@ -1039,7 +1078,13 @@ plat_pause(int p) p = get_vidpause(); /* If already so, done. */ - if (dopause == p) return; + if (dopause == p) { + /* Send the WM to a manager if needed. */ + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!dopause, (LPARAM) hwndMain); + + return; + } if (p) { wcscpy(oldtitle, ui_window_title(NULL));