From 468ef843994211acd98d4a6ea5c58f7a4fc6a3f1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 3 Aug 2022 13:05:21 +0600 Subject: [PATCH 01/33] qt: Enable and make VNC work properly --- src/qt/qt.c | 5 +++++ src/qt/qt_mainwindow.cpp | 32 +++++++++++++++++++++++++++++++- src/qt/qt_mainwindow.hpp | 1 + src/qt/qt_mainwindow.ui | 12 ++++++++++++ src/vnc.c | 10 ++++++---- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/qt/qt.c b/src/qt/qt.c index 68b204dbc..bb6d9658d 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -51,6 +51,8 @@ plat_vidapi(char* api) { return 4; } else if (!strcasecmp(api, "qt_d3d9")) { return 5; + } else if (!strcasecmp(api, "vnc")) { + return 6; } return 0; @@ -78,6 +80,9 @@ char* plat_vidapi_name(int api) { case 5: name = "qt_d3d9"; break; + case 6: + name = "vnc"; + break; default: fatal("Unknown renderer: %i\n", api); break; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 00ebb578e..f05c32ba6 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -46,6 +46,10 @@ extern "C" { #include <86box/vid_ega.h> #include <86box/version.h> +#ifdef USE_VNC +#include <86box/vnc.h> +#endif + extern int qt_nvr_save(void); #ifdef MTR_ENABLED @@ -141,6 +145,8 @@ MainWindow::MainWindow(QWidget *parent) : ((BWindow*)this->winId())->AddFilter(filter); #endif setUnifiedTitleAndToolBarOnMac(true); + extern MainWindow* main_window; + main_window = this; ui->setupUi(this); ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); @@ -308,6 +314,11 @@ MainWindow::MainWindow(QWidget *parent) : if (vid_api == 5) vid_api = 0; #endif +#ifndef USE_VNC + if (vid_api == 6) vid_api = 0; + ui->actionVNC->setVisible(false); +#endif + #if !QT_CONFIG(vulkan) if (vid_api == 4) vid_api = 0; ui->actionVulkan->setVisible(false); @@ -322,10 +333,20 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionOpenGL_3_0_Core); actGroup->addAction(ui->actionVulkan); actGroup->addAction(ui->actionDirect3D_9); + actGroup->addAction(ui->actionVNC); actGroup->setExclusive(true); connect(actGroup, &QActionGroup::triggered, [this](QAction* action) { vid_api = action->property("vid_api").toInt(); +#ifdef USE_VNC + if (vnc_enabled && vid_api != 6) { + startblit(); + vnc_enabled = 0; + vnc_close(); + video_setblit(qt_blit); + endblit(); + } +#endif RendererStack::Renderer newVidApi = RendererStack::Renderer::Software; switch (vid_api) { @@ -347,6 +368,15 @@ MainWindow::MainWindow(QWidget *parent) : case 5: newVidApi = (RendererStack::Renderer::Direct3D9); break; +#ifdef USE_VNC + case 6: + { + newVidApi = RendererStack::Renderer::Software; + startblit(); + vnc_enabled = vnc_init(nullptr); + endblit(); + } +#endif } ui->stackedWidget->switchRenderer(newVidApi); if (!show_second_monitors) return; @@ -469,7 +499,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); ui->actionTake_screenshot->setShortcutVisibleInContextMenu(true); #endif - video_setblit(qt_blit); + if (!vnc_enabled) video_setblit(qt_blit); if (start_in_fullscreen) { connect(ui->stackedWidget, &RendererStack::blit, this, [this] () { diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 0f8a5ecd2..c33decb44 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -144,6 +144,7 @@ private: bool send_keyboard_input = true; bool shownonce = false; bool resizableonce = false; + bool vnc_enabled = false; friend class SpecifyDimensions; friend class ProgSettings; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index f077f7e97..522d2f081 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -106,6 +106,7 @@ + @@ -766,6 +767,17 @@ Show non-primary monitors + + + true + + + VNC + + + 6 + + diff --git a/src/vnc.c b/src/vnc.c index 46ef21c5d..27df6cb22 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -172,8 +172,10 @@ vnc_blit(int x, int y, int w, int h, int monitor_index) uint32_t *p; int yy; - if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL)) - return; + if (monitor_index || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL)) { + video_blit_complete_monitor(monitor_index); + return; + } for (yy=0; yyframeBuffer)[yy*VNC_MAX_X]); @@ -185,7 +187,7 @@ vnc_blit(int x, int y, int w, int h, int monitor_index) if (screenshots) video_screenshot((uint32_t *) rfb->frameBuffer, 0, 0, VNC_MAX_X); - video_blit_complete(); + video_blit_complete_monitor(monitor_index); if (! updatingSize) rfbMarkRectAsModified(rfb, 0,0, allowedX,allowedY); @@ -210,7 +212,7 @@ vnc_init(UNUSED(void *arg)) 32, 32, 0, 1, 255,255,255, 16, 8, 0, 0, 0 }; - cgapal_rebuild(); + cgapal_rebuild_monitor(0); if (rfb == NULL) { wcstombs(title, ui_window_title(NULL), sizeof(title)); From 9473640552b05afc6d00fc76856eb0b28fb8c57d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 3 Aug 2022 13:38:44 +0600 Subject: [PATCH 02/33] mpu401: Add MPU-401AT I/O address ranges --- src/sound/snd_mpu401.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index cb442032c..10ef7b5e0 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1844,6 +1844,18 @@ static const device_config_t mpu401_standalone_config[] = { .description = "0x330", .value = 0x330 }, + { + .description = "0x332", + .value = 0x332 + }, + { + .description = "0x334", + .value = 0x334 + }, + { + .description = "0x336", + .value = 0x336 + }, { .description = "0x340", .value = 0x340 From 828334c48235723d0f58bd72e44968df418bc84d Mon Sep 17 00:00:00 2001 From: cold-brewed Date: Wed, 3 Aug 2022 12:18:41 -0400 Subject: [PATCH 03/33] qt: Update machine settings layout to make mac and linux consistent with windows layout --- src/qt/qt_settingsmachine.ui | 148 +++++++++++++++++------------------ 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 30f375f7e..d5ff1ca59 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -7,7 +7,7 @@ 0 0 458 - 390 + 391 @@ -28,7 +28,7 @@ - + 0 @@ -51,58 +51,55 @@ - + Machine: - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 0 + 0 + + + + Configure + + + + + + + CPU type: - - - - FPU: - - - - - - - Wait states: - - - - - - - Memory: - - - - - - - - - - - - - - 0 - 0 - - - - - + @@ -150,38 +147,41 @@ - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - 0 - 0 - - - - Configure - - - - + + + + FPU: + + + + + + + + + + Wait states: + + + + + + + + + + Memory: + + + + + + + + 0 + 0 + + From 93f01dfb2e0aef65433a69d43eb08c69e5ef1a9d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 4 Aug 2022 00:21:27 +0600 Subject: [PATCH 04/33] vnc: Pause always when switching to VNC renderer --- src/vnc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vnc.c b/src/vnc.c index 27df6cb22..0cc745883 100644 --- a/src/vnc.c +++ b/src/vnc.c @@ -212,6 +212,7 @@ vnc_init(UNUSED(void *arg)) 32, 32, 0, 1, 255,255,255, 16, 8, 0, 0, 0 }; + plat_pause(1); cgapal_rebuild_monitor(0); if (rfb == NULL) { From 0e9686371ea2eeecae85f3aaf944a3b6a5fbf825 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Aug 2022 01:41:52 +0200 Subject: [PATCH 05/33] Fixed OTi-0x7 clock select. --- src/video/vid_oak_oti.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 7572e44b6..cea26a71f 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -366,6 +366,7 @@ oti_getclock(int clock) break; } + return ret; } From 61828a89fc2ef1472c28c5537541a7dc02f6caa9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Aug 2022 04:39:37 +0200 Subject: [PATCH 06/33] Added the GC113 used by the real TriGem 286M, and fixed that EMS driver on GC113 onwards, closes #2567. --- src/chipset/headland.c | 93 +++++++++++++++++++++++++++++++----- src/include/86box/chipset.h | 3 ++ src/io.c | 4 +- src/machine/m_at_286_386sx.c | 10 ++-- 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/src/chipset/headland.c b/src/chipset/headland.c index ed2e318fc..91f1658d8 100644 --- a/src/chipset/headland.c +++ b/src/chipset/headland.c @@ -38,6 +38,23 @@ #include <86box/chipset.h> +enum { + HEADLAND_GC103 = 0x00, + HEADLAND_GC113 = 0x10, + HEADLAND_HT18_A = 0x11, + HEADLAND_HT18_B = 0x12, + HEADLAND_HT18_C = 0x18, + HEADLAND_HT21_C_D = 0x31, + HEADLAND_HT21_E = 0x32, +}; + + +#define HEADLAND_REV_MASK 0x0F + +#define HEADLAND_HAS_CRI 0x10 +#define HEADLAND_HAS_SLEEP 0x20 + + typedef struct { uint8_t valid, enabled; uint16_t mr; @@ -49,6 +66,7 @@ typedef struct { typedef struct headland_t { uint8_t revision; + uint8_t has_cri, has_sleep; uint8_t cri; uint8_t cr[7]; @@ -330,7 +348,7 @@ hl_write(uint16_t addr, uint8_t val, void *priv) break; case 0x01ed: - if (dev->revision > 0) + if (dev->has_cri) dev->cri = val; break; @@ -339,7 +357,7 @@ hl_write(uint16_t addr, uint8_t val, void *priv) break; case 0x01ef: - switch(dev->cri) { + switch(dev->cri & 0x07) { case 0: dev->cr[0] = (val & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; memmap_state_update(dev); @@ -352,11 +370,18 @@ hl_write(uint16_t addr, uint8_t val, void *priv) case 2: case 3: - case 5: dev->cr[dev->cri] = val; memmap_state_update(dev); break; + case 5: + if (dev->has_sleep) + dev->cr[dev->cri] = val; + else + dev->cr[dev->cri] = val & 0x0f; + memmap_state_update(dev); + break; + case 4: dev->cr[4] = (dev->cr[4] & 0xf0) | (val & 0x0f); memmap_state_update(dev); @@ -421,7 +446,7 @@ hl_read(uint16_t addr, void *priv) break; case 0x01ed: - if (dev->revision > 0) + if (dev->has_cri) ret = dev->cri; break; @@ -430,7 +455,7 @@ hl_read(uint16_t addr, void *priv) break; case 0x01ef: - switch(dev->cri) { + switch(dev->cri & 0x07) { case 0: ret = (dev->cr[0] & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; break; @@ -593,11 +618,14 @@ headland_init(const device_t *info) dev = (headland_t *) malloc(sizeof(headland_t)); memset(dev, 0x00, sizeof(headland_t)); - dev->revision = info->local; + dev->has_cri = (info->local & HEADLAND_HAS_CRI); + dev->has_sleep = (info->local & HEADLAND_HAS_SLEEP); + dev->revision = info->local & HEADLAND_REV_MASK; if (dev->revision > 0) ht386 = 1; + dev->cr[0] = 0x04; dev->cr[4] = dev->revision << 4; if (ht386) @@ -627,7 +655,7 @@ headland_init(const device_t *info) ram, MEM_MAPPING_INTERNAL, &dev->null_mr); if (mem_size > 640) { - mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x40000, + mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x60000, mem_read_b, mem_read_w, mem_read_l, mem_write_b, mem_write_w, mem_write_l, ram + 0xa0000, MEM_MAPPING_INTERNAL, &dev->null_mr); @@ -684,11 +712,26 @@ headland_init(const device_t *info) return(dev); } + const device_t headland_gc10x_device = { .name = "Headland GC101/102/103", .internal_name = "headland_gc10x", .flags = 0, - .local = 0, + .local = HEADLAND_GC103, + .init = headland_init, + .close = headland_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t headland_gc113_device = { + .name = "Headland GC101/102/113", + .internal_name = "headland_gc113", + .flags = 0, + .local = HEADLAND_GC113, .init = headland_init, .close = headland_close, .reset = NULL, @@ -702,7 +745,7 @@ const device_t headland_ht18a_device = { .name = "Headland HT18 Rev. A", .internal_name = "headland_ht18a", .flags = 0, - .local = 1, + .local = HEADLAND_HT18_A, .init = headland_init, .close = headland_close, .reset = NULL, @@ -716,7 +759,7 @@ const device_t headland_ht18b_device = { .name = "Headland HT18 Rev. B", .internal_name = "headland_ht18b", .flags = 0, - .local = 2, + .local = HEADLAND_HT18_B, .init = headland_init, .close = headland_close, .reset = NULL, @@ -730,7 +773,35 @@ const device_t headland_ht18c_device = { .name = "Headland HT18 Rev. C", .internal_name = "headland_ht18c", .flags = 0, - .local = 8, + .local = HEADLAND_HT18_C, + .init = headland_init, + .close = headland_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t headland_ht21c_d_device = { + .name = "Headland HT21 Rev. C/D", + .internal_name = "headland_ht21cd", + .flags = 0, + .local = HEADLAND_HT21_C_D, + .init = headland_init, + .close = headland_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t headland_ht21e_device = { + .name = "Headland HT21 Rev. E", + .internal_name = "headland_ht21", + .flags = 0, + .local = HEADLAND_HT21_E, .init = headland_init, .close = headland_close, .reset = NULL, diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index eddb37bff..cc36578fa 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -55,9 +55,12 @@ extern const device_t gc100a_device; /* Headland */ extern const device_t headland_gc10x_device; +extern const device_t headland_gc113_device; extern const device_t headland_ht18a_device; extern const device_t headland_ht18b_device; extern const device_t headland_ht18c_device; +extern const device_t headland_ht21c_d_device; +extern const device_t headland_ht21e_device; /* IMS */ extern const device_t ims8848_device; diff --git a/src/io.c b/src/io.c index 268305e1a..08e61f7ba 100644 --- a/src/io.c +++ b/src/io.c @@ -323,8 +323,8 @@ inb(uint16_t port) cycles -= io_delay; /* TriGem 486-BIOS MHz output. */ - if (port == 0x1ed) - ret = 0xfe; + /* if (port == 0x1ed) + ret = 0xfe; */ io_log("[%04X:%08X] (%i, %i, %04i) in b(%04X) = %02X\n", CS, cpu_state.pc, in_smm, found, qfound, port, ret); diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index fb4186c4e..e30272063 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -67,15 +67,17 @@ machine_at_mr286_init(const machine_t *model) } static void -machine_at_headland_common_init(int ht386) +machine_at_headland_common_init(int type) { device_add(&keyboard_at_ami_device); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - if (ht386) + if (type == 2) device_add(&headland_ht18b_device); + else if (type == 1) + device_add(&headland_gc113_device); else device_add(&headland_gc10x_device); } @@ -93,7 +95,7 @@ machine_at_tg286m_init(const machine_t *model) machine_at_common_ide_init(model); - machine_at_headland_common_init(0); + machine_at_headland_common_init(1); return ret; } @@ -114,7 +116,7 @@ machine_at_ama932j_init(const machine_t *model) if (gfxcard == VID_INTERNAL) device_add(&oti067_ama932j_device); - machine_at_headland_common_init(1); + machine_at_headland_common_init(2); return ret; } From ab154faf88ace1bba5503d1b20d6796f6a2f0852 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 4 Aug 2022 16:17:55 +0600 Subject: [PATCH 07/33] x86: mov r, DR6 now always writes bits 4-11 and bits 16-31 as 1 --- src/cpu/x86_ops_mov_ctrl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 667ea9d31..0d973338e 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -91,7 +91,7 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat) return 1; } fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); return 0; @@ -104,7 +104,7 @@ static int opMOV_r_DRx_a32(uint32_t fetchdat) return 1; } fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg]; + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); CLOCK_CYCLES(6); PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); return 0; From 64195df373f28de8bc806781e2873773e7eda047 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 4 Aug 2022 16:43:21 +0600 Subject: [PATCH 08/33] 386: set bit 14 of DR6 to 1 on INT 01 with TF set --- src/cpu/386.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/386.c b/src/cpu/386.c index 5f30e1199..d6d4ded16 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -196,6 +196,7 @@ exec386(int cycs) enter_smm_check(0); else if (trap) { flags_rebuild(); + dr[6] |= 0x4000; if (msw&1) pmodeint(1,0); else { From c743d360282736f038510997b909708245dfe7e6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 4 Aug 2022 18:04:40 +0600 Subject: [PATCH 09/33] 386: Set BS flag in DR6 other interpreter as well --- src/cpu/386_dynarec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 3e4d91ed2..f90ce5f80 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -404,6 +404,7 @@ exec386_dynarec_int(void) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; x86_int(1); } From 730af4dd536b2d043c7aa13405bc4dc332adbced Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 4 Aug 2022 23:52:25 +0200 Subject: [PATCH 10/33] Implemented more previously unimplemented AT NVR behavior. --- src/nvr_at.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/nvr_at.c b/src/nvr_at.c index bb4c38b85..eb749ff49 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -467,10 +467,10 @@ timer_update(void *priv) nvr->regs[RTC_REGC] |= REGC_AF; if (nvr->regs[RTC_REGB] & REGB_AIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } @@ -481,10 +481,10 @@ timer_update(void *priv) nvr->regs[RTC_REGC] |= REGC_UF; if (nvr->regs[RTC_REGB] & REGB_UIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } } @@ -533,10 +533,10 @@ timer_intr(void *priv) nvr->regs[RTC_REGC] |= REGC_PF; if (nvr->regs[RTC_REGB] & REGB_PIE) { /* Generate an interrupt. */ - if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) - picint(1 << nvr->irq); - - nvr->regs[RTC_REGC] |= REGC_IRQF; + if ((nvr->irq != -1) && (!(nvr->regs[RTC_REGC] & REGC_IRQF))) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } } } } @@ -592,6 +592,7 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) local_t *local = (local_t *)nvr->data; struct tm tm; uint8_t old; + uint8_t irq = 0, old_irq = 0; old = nvr->regs[reg]; switch(reg) { @@ -601,12 +602,21 @@ nvr_reg_write(uint16_t reg, uint8_t val, void *priv) break; case RTC_REGB: + old_irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; nvr->regs[RTC_REGB] = val; if (((old^val) & REGB_SET) && (val & REGB_SET)) { /* According to the datasheet... */ nvr->regs[RTC_REGA] &= ~REGA_UIP; nvr->regs[RTC_REGB] &= ~REGB_UIE; } + irq = (nvr->regs[RTC_REGB] & nvr->regs[RTC_REGC]) & 0x70; + if (old_irq && !irq) { + picintc(1 << nvr->irq); + nvr->regs[RTC_REGC] &= ~REGC_IRQF; + } else if (!old_irq && irq) { + picintlevel(1 << nvr->irq); + nvr->regs[RTC_REGC] |= REGC_IRQF; + } break; case RTC_REGC: /* R/O */ @@ -694,8 +704,8 @@ nvr_read(uint16_t addr, void *priv) break; case RTC_REGC: - picintc(1 << nvr->irq); ret = nvr->regs[RTC_REGC]; + picintc(1 << nvr->irq); nvr->regs[RTC_REGC] = 0x00; break; From be063529daebc47dcbe35c454174dd7b0c623cf0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 5 Aug 2022 15:04:26 +0600 Subject: [PATCH 11/33] NVR: Don't fatal on failure to read NVR properly --- src/nvr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/nvr.c b/src/nvr.c index b73aa6fa7..a68331e34 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -237,6 +237,7 @@ nvr_load(void) { char *path; FILE *fp; + uint8_t regs[NVR_MAXSIZE] = { 0 }; /* Make sure we have been initialized. */ if (saved_nvr == NULL) return(0); @@ -255,9 +256,12 @@ nvr_load(void) fp = plat_fopen(path, "rb"); saved_nvr->is_new = (fp == NULL); if (fp != NULL) { + memcpy(regs, saved_nvr->regs, sizeof(regs)); /* Read NVR contents from file. */ - if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) - fatal("nvr_load(): Error reading data\n"); + if (fread(saved_nvr->regs, 1, saved_nvr->size, fp) != saved_nvr->size) { + memcpy(saved_nvr->regs, regs, sizeof(regs)); + saved_nvr->is_new = 1; + } (void)fclose(fp); } } else From 0faca6ae49d3d2eca7f6c951fb9953df2c712c8c Mon Sep 17 00:00:00 2001 From: Robert de Rooy Date: Fri, 5 Aug 2022 18:22:03 +0200 Subject: [PATCH 12/33] use zip for roms to prevent clobbering --- src/unix/assets/86Box.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index d5fe0a0b1..2f48d1687 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -20,7 +20,7 @@ License: GPLv2+ URL: https://86box.net Source0: https://github.com/86Box/86Box/archive/refs/tags/v%%{version}.tar.gz -Source1: https://github.com/86Box/roms/archive/refs/tags/%{version}.tar.gz +Source1: https://github.com/86Box/roms/archive/refs/tags/v%{version}.zip BuildRequires: cmake BuildRequires: desktop-file-utils From 1ec594b28152c6a7ae9b42caca347380d7f399a7 Mon Sep 17 00:00:00 2001 From: Robert de Rooy Date: Fri, 5 Aug 2022 21:09:37 +0200 Subject: [PATCH 13/33] revert ROM package back to it's own version --- bumpversion.sh | 11 ++++++++++- src/unix/assets/86Box.spec | 8 +++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/bumpversion.sh b/bumpversion.sh index 31ebf154b..ac6116bcc 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -17,9 +17,11 @@ # Parse arguments. newversion="$1" +romversion="$2" + if [ -z "$(echo "$newversion" | grep '\.')" ] then - echo '[!] Usage: bumpversion.sh x.y[.z]' + echo '[!] Usage: bumpversion.sh x.y[.z] [romversion]' exit 1 fi shift @@ -30,6 +32,12 @@ newversion_min=$(echo "$newversion" | cut -d. -f2) newversion_patch=$(echo "$newversion" | cut -d. -f3) [ -z "$newversion_patch" ] && newversion_patch=0 +if [ -z "${romversion}" ]; then + # Get the latest ROM release from the GitHub API. + romversion=$(curl --silent "https://api.github.com/repos/86Box/roms/releases/latest" | + grep '"tag_name":' | + sed -E 's/.*"([^"]+)".*/\1/') +fi # Switch to the repository root directory. cd "$(dirname "$0")" || exit @@ -61,6 +69,7 @@ patch_file src/include_make/*/version.h EMU_VERSION_PATCH 's/(#\s*define\s+EMU_V patch_file src/include_make/*/version.h COPYRIGHT_YEAR 's/(#\s*define\s+COPYRIGHT_YEAR\s+)[0-9]+/\1'"$(date +%Y)"'/' patch_file src/include_make/*/version.h EMU_DOCS_URL 's/(#\s*define\s+EMU_DOCS_URL\s+"https:\/\/[^\/]+\/en\/v)[^\/]+/\1'"$newversion_maj.$newversion_min"'/' patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' +patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/' patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' patch_file src/unix/assets/*.metainfo.xml release 's/( Date: Fri, 5 Aug 2022 23:12:03 +0200 Subject: [PATCH 14/33] qt: fix busy looping with evdev mouse Replace busy looping which was using 100% cpu with poll() --- src/qt/evdev_mouse.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 120f4572c..186f49813 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -31,6 +31,7 @@ extern "C" #include <86box/86box.h> #include <86box/plat.h> #include <86box/mouse.h> +#include } static std::vector> evdev_mice; @@ -54,25 +55,40 @@ void evdev_mouse_poll() void evdev_thread_func() { + struct pollfd *pfds = (struct pollfd*)calloc(evdev_mice.size(), sizeof(struct pollfd)); + for (unsigned int i = 0; i < evdev_mice.size(); i++) + { + pfds[i].fd = libevdev_get_fd(evdev_mice[i].second); + pfds[i].events = POLLIN; + } + while (!stopped) { + poll(pfds, evdev_mice.size(), 500); for (unsigned int i = 0; i < evdev_mice.size(); i++) { struct input_event ev; - int rc = libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev); - if (rc == 0 && ev.type == EV_REL && mouse_capture) - { - if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; - if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + if (pfds[i].revents & POLLIN) { + int rc; + while ((rc = libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev)) == 0) + { + if (ev.type == EV_REL && mouse_capture) + { + if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; + if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + } + } } } } + for (unsigned int i = 0; i < evdev_mice.size(); i++) { libevdev_free(evdev_mice[i].second); evdev_mice[i].second = nullptr; close(evdev_mice[i].first); } + free(pfds); evdev_mice.clear(); } From ce4d7f9fc886a04ac743b1c85a39dec3b9bf8e1b Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Fri, 5 Aug 2022 23:22:39 +0200 Subject: [PATCH 15/33] Small cleanup --- src/qt/evdev_mouse.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 186f49813..5ad252f1a 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -69,8 +69,7 @@ void evdev_thread_func() { struct input_event ev; if (pfds[i].revents & POLLIN) { - int rc; - while ((rc = libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev)) == 0) + while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) { if (ev.type == EV_REL && mouse_capture) { From 68812d4368355b04042526b7abd1fda01d5ac6da Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Sat, 6 Aug 2022 11:51:39 +0200 Subject: [PATCH 16/33] qt_openglrenderer: fix fullscreen rendering on mac --- src/qt/qt_openglrenderer.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 3a5f58846..cce5b5014 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -95,8 +95,8 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event) context->makeCurrent(this); glViewport( - destination.x(), - destination.y(), + destination.x() * devicePixelRatio(), + destination.y() * devicePixelRatio(), destination.width() * devicePixelRatio(), destination.height() * devicePixelRatio()); } @@ -179,8 +179,8 @@ OpenGLRenderer::initialize() glClearColor(0.f, 0.f, 0.f, 1.f); glViewport( - destination.x(), - destination.y(), + destination.x() * devicePixelRatio(), + destination.y() * devicePixelRatio(), destination.width() * devicePixelRatio(), destination.height() * devicePixelRatio()); @@ -425,6 +425,14 @@ OpenGLRenderer::onBlit(int buf_idx, int x, int y, int w, int h) context->makeCurrent(this); +#ifdef Q_OS_MACOS + glViewport( + destination.x() * devicePixelRatio(), + destination.y() * devicePixelRatio(), + destination.width() * devicePixelRatio(), + destination.height() * devicePixelRatio()); +#endif + if (source.width() != w || source.height() != h) { source.setRect(0, 0, w, h); From 3a1d9cff9aa70c3e434b878a091255e20485fe87 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Sat, 6 Aug 2022 14:23:11 +0200 Subject: [PATCH 17/33] Add an instrumentation option for performance profiling Not built by default, this allows printing the emulation speed on stdout and exiting after a certain emulation time. --- src/86box.c | 10 ++++++++++ src/CMakeLists.txt | 4 ++++ src/include/86box/86box.h | 4 ++++ src/qt/qt_main.cpp | 12 ++++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/86box.c b/src/86box.c index deded3382..56847b2a9 100644 --- a/src/86box.c +++ b/src/86box.c @@ -138,6 +138,10 @@ char rom_path[1024] = { '\0'}; /* (O) full path to ROMs */ rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */ char log_path[1024] = { '\0'}; /* (O) full path of logfile */ char vm_name[1024] = { '\0'}; /* (O) display name of the VM */ +#ifdef USE_INSTRUMENT +uint8_t instru_enabled = 0; +uint64_t instru_run_ms = 0; +#endif /* Configuration values. */ int window_remember; @@ -567,6 +571,12 @@ usage: /* .. and then exit. */ return(0); +#ifdef USE_INSTRUMENT + } else if (!strcasecmp(argv[c], "--instrument")) { + if ((c+1) == argc) goto usage; + instru_enabled = 1; + sscanf(argv[++c], "%llu", &instru_run_ms); +#endif } /* Uhm... out of options here.. */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1420aaa89..428d5b521 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,10 @@ if(VNC) endif() endif() +if(INSTRUMENT) + add_compile_definitions(USE_INSTRUMENT) +endif() + target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom zip mo hdd net print scsi sio snd vid voodoo plat ui) diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index ca7fbb99c..30a7542dc 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -76,6 +76,10 @@ extern uint64_t source_hwnd; extern char rom_path[1024]; /* (O) full path to ROMs */ extern char log_path[1024]; /* (O) full path of logfile */ extern char vm_name[1024]; /* (O) display name of the VM */ +#ifdef USE_INSTRUMENT +extern uint8_t instru_enabled; +extern uint64_t instru_run_ms; +#endif #define window_x monitor_settings[0].mon_window_x #define window_y monitor_settings[0].mon_window_y diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a74958511..df35095b9 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -109,9 +109,21 @@ main_thread_fn() if (drawits > 50) drawits = 0; +#ifdef USE_INSTRUMENT + uint64_t start_time = elapsed_timer.nsecsElapsed(); +#endif /* Run a block of code. */ pc_run(); +#ifdef USE_INSTRUMENT + if (instru_enabled) { + uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; + uint64_t total_elapsed_us = (uint64_t)((double)tsc / cpu_s->rspeed * 1000); + printf("[instrument] %llu, %llu\n", total_elapsed_us, elapsed_us); + if (instru_run_ms && total_elapsed_us >= instru_run_ms) + break; + } +#endif /* Every 200 frames we save the machine status. */ if (++frames >= 200 && nvr_dosave) { qt_nvr_save(); From c6cf8486932c902ab0f03fcd889b046f91517cf4 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Sat, 6 Aug 2022 14:51:42 +0200 Subject: [PATCH 18/33] Fix var name --- src/qt/qt_main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index df35095b9..694a0e5f6 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -118,9 +118,9 @@ main_thread_fn() #ifdef USE_INSTRUMENT if (instru_enabled) { uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; - uint64_t total_elapsed_us = (uint64_t)((double)tsc / cpu_s->rspeed * 1000); - printf("[instrument] %llu, %llu\n", total_elapsed_us, elapsed_us); - if (instru_run_ms && total_elapsed_us >= instru_run_ms) + uint64_t total_elapsed_ms = (uint64_t)((double)tsc / cpu_s->rspeed * 1000); + printf("[instrument] %llu, %llu\n", total_elapsed_ms, elapsed_us); + if (instru_run_ms && total_elapsed_ms >= instru_run_ms) break; } #endif From 4bd7cf3653507814cb84e5c45bda59d6a2576494 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Aug 2022 23:35:12 +0200 Subject: [PATCH 19/33] Made AAM with base 0 work as before, fixes Microsoft Flight Simulator 98. --- src/cpu/x86_ops_bcd.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index b37b6a6df..2f64cbaf8 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -32,12 +32,7 @@ static int opAAM(uint32_t fetchdat) { int base = getbytef(); - if (base == 0) { - x86de(NULL, 0); - return 1; - } - - if (!cpu_isintel) base = 10; + if (!base || !cpu_isintel) base = 10; AH = AL / base; AL %= base; From 745c9f3eb52bd614c08926e9939ad396aa0bc361 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Aug 2022 02:24:20 +0200 Subject: [PATCH 20/33] Another fix. --- src/cpu/x86_ops_bcd.h | 7 ++++++- src/cpu/x86seg.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index 2f64cbaf8..efb0de264 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -32,7 +32,12 @@ static int opAAM(uint32_t fetchdat) { int base = getbytef(); - if (!base || !cpu_isintel) base = 10; + if (base == 0) { + x86de(NULL, 0); + return 1; + } + + if (!cpu_isintel) base = 10; AH = AL / base; AL %= base; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index c9398dd69..2fda437e7 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -168,8 +168,12 @@ x86_doabrt(int x86_abrt) void x86de(char *s, uint16_t error) { +#ifdef BAD_CODE cpu_state.abrt = ABRT_DE; abrt_error = error; +#else + x86_int(0); +#endif } From 3407708a9efbc0f2a1686e421f2c75283fe576d3 Mon Sep 17 00:00:00 2001 From: Dominus Iniquitatis Date: Mon, 8 Aug 2022 06:52:20 +0300 Subject: [PATCH 21/33] qt: Adjusted "Controller 4" vertical position --- src/qt/qt_settingsstoragecontrollers.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index c4c44b019..30a59f982 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -172,7 +172,7 @@ - + Controller 4: From 4cb84a3a805be6c1bd2af566042eeb5cd4971341 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Mon, 8 Aug 2022 23:55:58 +0200 Subject: [PATCH 22/33] Optimize svga_render_blank --- src/video/vid_svga_render.c | 40 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 17b4c4981..8c4735d4f 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -43,35 +43,29 @@ svga_render_null(svga_t *svga) void svga_render_blank(svga_t *svga) { - int x, xx; - if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; + svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x < (svga->hdisp + svga->scrollcache); x++) { - switch (svga->seqregs[1] & 9) { - case 0: - for (xx = 0; xx < 9; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 9) + xx] = 0x00000000; - break; - case 1: - for (xx = 0; xx < 8; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 8) + xx] = 0x00000000; - break; - case 8: - for (xx = 0; xx < 18; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 18) + xx] = 0x00000000; - break; - case 9: - for (xx = 0; xx < 16; xx++) - buffer32->line[svga->displine + svga->y_add][svga->x_add + (x * 16) + xx] = 0x00000000; - break; - } + uint32_t char_width = 0; + + switch (svga->seqregs[1] & 9) { + case 0: + char_width = 9; + case 1: + char_width = 8; + case 8: + char_width = 18; + case 9: + char_width = 16; } + + uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); + memset(line_ptr, 0, line_width); } From ce95d2e7bde908ea1a414061ae86afeabdc542a4 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Tue, 9 Aug 2022 00:29:04 +0200 Subject: [PATCH 23/33] Optimize svga_render_overscan --- src/video/vid_svga_render.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 8c4735d4f..3e8f53286 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -75,13 +75,14 @@ svga_render_overscan_left(svga_t *svga) int i; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->scrblank || (svga->hdisp == 0)) - return; + return; + uint32_t *line_ptr = buffer32->line[svga->displine + svga->y_add]; for (i = 0; i < svga->x_add; i++) - buffer32->line[svga->displine + svga->y_add][i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; } @@ -91,14 +92,15 @@ svga_render_overscan_right(svga_t *svga) int i, right; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->scrblank || (svga->hdisp == 0)) - return; + return; + uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp]; 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; + *line_ptr++ = svga->overscan_color; } From d3e6d13a84486f3f3ede97e964ef2ceef2739761 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Tue, 9 Aug 2022 01:37:29 +0200 Subject: [PATCH 24/33] Fix stupid mistake in svga_render_blank --- src/video/vid_svga_render.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 3e8f53286..3a8c4b10a 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -55,12 +55,16 @@ svga_render_blank(svga_t *svga) switch (svga->seqregs[1] & 9) { case 0: char_width = 9; + break; case 1: char_width = 8; + break; case 8: char_width = 18; + break; case 9: char_width = 16; + break; } uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; From 2a6a0615569cc0eebfbdbb2a1624808125e49fe7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Aug 2022 04:34:48 +0200 Subject: [PATCH 25/33] nmi_raise() actually raises NMI, should fix ES1371 legacy device and other stuff. --- src/cpu/386_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 92360a248..3c0cd168a 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -1897,6 +1897,8 @@ nmi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x20000000)) cpu_fast_off_advance(); + + nmi = 1; } From f70102c52966db845ba5b11841917122ee88ef9c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 9 Aug 2022 15:35:32 +0600 Subject: [PATCH 26/33] qt: Add ability to open screenshots folder --- src/qt/qt_mainwindow.cpp | 8 ++++++++ src/qt/qt_mainwindow.hpp | 2 ++ src/qt/qt_mainwindow.ui | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f05c32ba6..38abfda62 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -74,6 +74,7 @@ extern "C" { #include #include #include +#include #include #include @@ -2122,3 +2123,10 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() blitDummied = false; } + +void MainWindow::on_actionOpen_screenshots_folder_triggered() +{ + QDir(QString(usr_path) + QString("/screenshots/")).mkpath("."); + QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index c33decb44..feb50fb94 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -129,6 +129,8 @@ protected: private slots: void on_actionShow_non_primary_monitors_triggered(); + void on_actionOpen_screenshots_folder_triggered(); + private: Ui::MainWindow *ui; std::unique_ptr status; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 522d2f081..b1e954693 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -91,6 +91,8 @@ + + @@ -778,6 +780,11 @@ 6 + + + Open screenshots folder... + + From 4c4ac5438a5f2a81dfd6492412fcbbe2342ed1ff Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Tue, 9 Aug 2022 18:13:21 +0200 Subject: [PATCH 27/33] Optimize timer processing Around 25% faster timer processing --- src/include/86box/timer.h | 27 +++++------------- src/timer.c | 58 ++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 51 deletions(-) diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index afbcec140..fcccb8494 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -198,30 +198,12 @@ extern pc_timer_t * timer_head; extern int timer_inited; -static __inline void -timer_remove_head_inline(void) -{ - pc_timer_t *timer; - - if (timer_inited && timer_head) { - timer = timer_head; - timer_head = timer->next; - if (timer_head) { - timer_head->prev = NULL; - timer->next->prev = NULL; - } - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - } -} - - static __inline void timer_process_inline(void) { pc_timer_t *timer; - if (!timer_inited || !timer_head) + if (!timer_head) return; while(1) { @@ -230,7 +212,12 @@ timer_process_inline(void) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) break; - timer_remove_head_inline(); + timer_head = timer->next; + if (timer_head) + timer_head->prev = NULL; + + timer->next = timer->prev = NULL; + timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ diff --git a/src/timer.c b/src/timer.c index 32d382d54..f8e17be2e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -41,20 +41,31 @@ timer_enable(pc_timer_t *timer) return; } - timer_node = timer_head; + if (TIMER_LESS_THAN(timer, timer_head)) { + timer->next = timer_head; + timer->prev = NULL; + timer_head->prev = timer; + timer_head = timer; + timer_target = timer_head->ts.ts32.integer; + return; + } + + if (!timer_head->next) { + timer_head->next = timer; + timer->prev = timer_head; + return; + } + + pc_timer_t *prev = timer_head; + timer_node = timer_head->next; while(1) { /*Timer expires before timer_node. Add to list in front of timer_node*/ if (TIMER_LESS_THAN(timer, timer_node)) { timer->next = timer_node; - timer->prev = timer_node->prev; + timer->prev = prev; timer_node->prev = timer; - if (timer->prev) - timer->prev->next = timer; - else { - timer_head = timer; - timer_target = timer_head->ts.ts32.integer; - } + prev->next = timer; return; } @@ -65,6 +76,7 @@ timer_enable(pc_timer_t *timer) return; } + prev = timer_node; timer_node = timer_node->next; } } @@ -91,33 +103,12 @@ timer_disable(pc_timer_t *timer) } -void -timer_remove_head(void) -{ - pc_timer_t *timer; - - if (!timer_inited) - return; - - if (timer_head) { - timer = timer_head; - timer_head = timer->next; - if (timer_head) { - timer_head->prev = NULL; - timer->next->prev = NULL; - } - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - } -} - - void timer_process(void) { pc_timer_t *timer; - if (!timer_inited || !timer_head) + if (!timer_head) return; while(1) { @@ -126,7 +117,12 @@ timer_process(void) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) break; - timer_remove_head(); + timer_head = timer->next; + if (timer_head) + timer_head->prev = NULL; + + timer->next = timer->prev = NULL; + timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ From 26d6b308a90631b545e92f46b55a406118147021 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Tue, 9 Aug 2022 19:14:42 +0200 Subject: [PATCH 28/33] Optimize IO in Around 36% faster --- src/include/86box/m_amstrad.h | 2 +- src/io.c | 73 +++++++++++++++++++++-------------- src/machine/m_amstrad.c | 5 ++- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/include/86box/m_amstrad.h b/src/include/86box/m_amstrad.h index c33d10c70..1b99617ca 100644 --- a/src/include/86box/m_amstrad.h +++ b/src/include/86box/m_amstrad.h @@ -20,7 +20,7 @@ #ifndef MACHINE_AMSTRAD_H #define MACHINE_AMSTRAD_H -extern int amstrad_latch; +extern uint32_t amstrad_latch; enum { AMSTRAD_NOLATCH, diff --git a/src/io.c b/src/io.c index 08e61f7ba..6501a199a 100644 --- a/src/io.c +++ b/src/io.c @@ -312,12 +312,14 @@ inb(uint16_t port) p = q; } - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; @@ -401,12 +403,14 @@ inw(uint16_t port) } ret = (ret8[1] << 8) | ret8[0]; - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; @@ -487,17 +491,26 @@ inl(uint16_t port) ret16[0] = ret & 0xffff; ret16[1] = (ret >> 16) & 0xffff; - for (i = 0; i < 4; i += 2) { - p = io[(port + i) & 0xffff]; - while(p) { - q = p->next; - if (p->inw && !p->inl) { - ret16[i >> 1] &= p->inw(port + i, p->priv); - found |= 2; - qfound++; - } - p = q; - } + p = io[port & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[0] &= p->inw(port, p->priv); + found |= 2; + qfound++; + } + p = q; + } + + p = io[(port + 2) & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[1] &= p->inw(port + 2, p->priv); + found |= 2; + qfound++; + } + p = q; } ret = (ret16[1] << 16) | ret16[0]; @@ -519,12 +532,14 @@ inl(uint16_t port) } ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 5dc82226d..eb934ebd1 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -156,7 +156,7 @@ typedef struct { fdc_t *fdc; } amstrad_t; -int amstrad_latch; +uint32_t amstrad_latch; static uint8_t key_queue[16]; static int key_queue_start = 0, @@ -2255,7 +2255,7 @@ ams_read(uint16_t port, void *priv) else if (video_is_mda()) ret |= 0xc0; - switch (amstrad_latch) { + switch (amstrad_latch & 0x7fffffff) { case AMSTRAD_NOLATCH: ret &= ~0x20; break; @@ -2293,6 +2293,7 @@ machine_amstrad_init(const machine_t *model, int type) ams = (amstrad_t *) malloc(sizeof(amstrad_t)); memset(ams, 0x00, sizeof(amstrad_t)); ams->type = type; + amstrad_latch = 0x80000000; switch (type) { case AMS_PC200: From dd233978544d3d88f6aeec10c7123c959a6a364e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 10 Aug 2022 01:27:54 +0600 Subject: [PATCH 29/33] qt: Add option to apply fullscreen stretching modes when maximized --- src/86box.c | 1 + src/config.c | 7 +++++++ src/include/86box/video.h | 1 + src/qt/qt_d3d9renderer.cpp | 2 ++ src/qt/qt_hardwarerenderer.cpp | 3 +++ src/qt/qt_hardwarerenderer.hpp | 4 ++++ src/qt/qt_mainwindow.cpp | 25 ++++++++++++++++++++++++- src/qt/qt_mainwindow.hpp | 5 ++++- src/qt/qt_mainwindow.ui | 9 +++++++++ src/qt/qt_openglrenderer.cpp | 2 ++ src/qt/qt_renderercommon.cpp | 2 +- src/qt/qt_renderercommon.hpp | 2 +- src/qt/qt_rendererstack.cpp | 1 + src/qt/qt_rendererstack.hpp | 4 ++++ src/qt/qt_softwarerenderer.cpp | 3 +++ src/qt/qt_vulkanwindowrenderer.cpp | 2 ++ 16 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/86box.c b/src/86box.c index 56847b2a9..85845b050 100644 --- a/src/86box.c +++ b/src/86box.c @@ -188,6 +188,7 @@ int enable_discord = 0; /* (C) enable Discord integration */ int pit_mode = -1; /* (C) force setting PIT mode */ int fm_driver = 0; /* (C) select FM sound driver */ int open_dir_usr_path = 0; /* default file open dialog directory of usr_path */ +int video_fullscreen_scale_maximized = 0; /* (C) Whether fullscreen scaling settings also apply when maximized. */ /* Statistics. */ extern int mmuflush; diff --git a/src/config.c b/src/config.c index 2a2f58c6c..768bbe3e4 100644 --- a/src/config.c +++ b/src/config.c @@ -969,6 +969,8 @@ load_video(void) ibm8514_enabled = !!config_get_int(cat, "8514a", 0); xga_enabled = !!config_get_int(cat, "xga", 0); show_second_monitors = !!config_get_int(cat, "show_second_monitors", 1); + video_fullscreen_scale_maximized = !!config_get_int(cat, "video_fullscreen_scale_maximized", 0); + p = config_get_string(cat, "gfxcard_2", NULL); if (!p) p = "none"; @@ -2554,6 +2556,11 @@ save_video(void) else config_set_int(cat, "show_second_monitors", show_second_monitors); + if (video_fullscreen_scale_maximized == 0) + config_delete_var(cat, "video_fullscreen_scale_maximized"); + else + config_set_int(cat, "video_fullscreen_scale_maximized", video_fullscreen_scale_maximized); + delete_section_if_empty(cat); } diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 8661fcef8..85c95c98d 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -133,6 +133,7 @@ extern atomic_bool doresize_monitors[MONITORS_NUM]; extern int monitor_index_global; extern int gfxcard_2; extern int show_second_monitors; +extern int video_fullscreen_scale_maximized; typedef rgb_t PALETTE[256]; diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index e7ef16f77..96718a4a2 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -145,6 +145,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h) return; } surfaceInUse = true; + auto origSource = source; source.setRect(x, y, w, h); RECT srcRect; D3DLOCKED_RECT lockRect; @@ -164,6 +165,7 @@ void D3D9Renderer::blit(int x, int y, int w, int h) d3d9surface->UnlockRect(); } else video_blit_complete_monitor(m_monitor_index); + if (origSource != source) onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); surfaceInUse = false; QTimer::singleShot(0, this, [this] { this->update(); }); } diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index 30ca74ecd..3577234ee 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -134,6 +134,7 @@ void HardwareRenderer::initializeGL() pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); glClearColor(0, 0, 0, 1); + m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); } void HardwareRenderer::paintGL() { @@ -187,6 +188,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { auto tval = this; void* nuldata = 0; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + auto origSource = source; if (!m_texture || !m_texture->isCreated()) { buf_usage[buf_idx].clear(); @@ -197,6 +199,7 @@ void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)imagebufs[buf_idx].get()); buf_usage[buf_idx].clear(); source.setRect(x, y, w, h); + if (origSource != source) onResize(this->width(), this->height()); update(); } diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index af4f05464..b9b7895e0 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -47,6 +47,10 @@ public: void resizeGL(int w, int h) override; void initializeGL() override; void paintGL() override; + void exposeEvent(QExposeEvent* event) override + { + onResize(size().width(), size().height()); + } std::vector> getBuffers() override; HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 38abfda62..c19dc4f54 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -133,6 +133,8 @@ std::atomic blitDummied{false}; extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); +extern MainWindow* main_window; + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -293,6 +295,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionShow_non_primary_monitors->setChecked(show_second_monitors); ui->actionUpdate_status_bar_icons->setChecked(update_icons); ui->actionEnable_Discord_integration->setChecked(enable_discord); + ui->actionApply_fullscreen_stretch_mode_when_maximized->setChecked(video_fullscreen_scale_maximized); #if defined Q_OS_WINDOWS || defined Q_OS_MACOS /* Make the option visible only if ANGLE is loaded. */ @@ -1773,11 +1776,15 @@ static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* sele ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); ui->actionFullScreen_int->setChecked(ui->actionFullScreen_int == selected); - if (video_fullscreen > 0) { + { auto widget = ui->stackedWidget->currentWidget(); ui->stackedWidget->onResize(widget->width(), widget->height()); } + for (int i = 1; i < MONITORS_NUM; i++) { + if (main_window->renderers[i]) main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); + } + device_force_redraw(); config_save(); } @@ -2130,3 +2137,19 @@ void MainWindow::on_actionOpen_screenshots_folder_triggered() QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); } + +void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked) +{ + video_fullscreen_scale_maximized = checked; + + auto widget = ui->stackedWidget->currentWidget(); + ui->stackedWidget->onResize(widget->width(), widget->height()); + + for (int i = 1; i < MONITORS_NUM; i++) { + if (renderers[i]) renderers[i]->onResize(renderers[i]->width(), renderers[i]->height()); + } + + device_force_redraw(); + config_save(); +} + diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index feb50fb94..c48333706 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -33,6 +33,8 @@ public: void blitToWidget(int x, int y, int w, int h, int monitor_index); QSize getRenderWidgetSize(); void setSendKeyboardInput(bool enabled); + + std::array, 8> renderers; signals: void paint(const QImage& image); void resizeContents(int w, int h); @@ -131,10 +133,11 @@ private slots: void on_actionOpen_screenshots_folder_triggered(); + void on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked); + private: Ui::MainWindow *ui; std::unique_ptr status; - std::array, 8> renderers; std::shared_ptr mm; #ifdef Q_OS_MACOS diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index b1e954693..3551eddb1 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -179,6 +179,7 @@ + @@ -785,6 +786,14 @@ Open screenshots folder... + + + true + + + Apply fullscreen stretch mode when maximized + + diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index cce5b5014..115e6af7f 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -80,6 +80,8 @@ OpenGLRenderer::exposeEvent(QExposeEvent *event) if (!isInitialized) initialize(); + + onResize(size().width(), size().height()); } void diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 0974c1f78..bb4903ee8 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -47,7 +47,7 @@ static void integer_scale(double *d, double *g) { } void RendererCommon::onResize(int width, int height) { - if (video_fullscreen == 0) { + if (video_fullscreen == 0 && video_fullscreen_scale_maximized ? (parentWidget->isMaximized() == false && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1) { destination.setRect(0, 0, width, height); return; } diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 1a0bf73e1..4a1b18341 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -37,7 +37,7 @@ public: protected: bool eventDelegate(QEvent *event, bool &result); - QRect source, destination; + QRect source{0, 0, 0, 0}, destination; QWidget *parentWidget { nullptr }; std::vector buf_usage; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 273bc4c95..3ff223ce4 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -397,6 +397,7 @@ RendererStack::createRenderer(Renderer renderer) if (current.get() == nullptr) return; current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); + current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); addWidget(current.get()); this->setStyleSheet("background-color: black"); diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 75cabec49..b2eccc84a 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -32,6 +32,10 @@ public: void wheelEvent(QWheelEvent *event) override; void leaveEvent(QEvent *event) override; void closeEvent(QCloseEvent *event) override; + void resizeEvent(QResizeEvent *event) override + { + onResize(event->size().width(), event->size().height()); + } void keyPressEvent(QKeyEvent *event) override { event->ignore(); diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 850e8369a..44a69c144 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -57,11 +57,14 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { auto tval = this; void* nuldata = 0; if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + auto origSource = source; cur_image = buf_idx; buf_usage[(buf_idx + 1) % 2].clear(); source.setRect(x, y, w, h); + + if (source != origSource) onResize(this->width(), this->height()); update(); } diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index cb3b96e14..629665d62 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -836,9 +836,11 @@ bool VulkanWindowRenderer::event(QEvent *event) void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { + auto origSource = source; source.setRect(x, y, w, h); if (isExposed()) requestUpdate(); buf_usage[0].clear(); + if (origSource != source) onResize(this->width(), this->height()); } uint32_t VulkanWindowRenderer::getBytesPerRow() From 0c2d9cb2891009c6cd53036e7ca9fc1ab8d10d3b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Aug 2022 23:16:38 +0200 Subject: [PATCH 30/33] XGA: Cursor no longer gets black parts when returning from Mystify screensaver to GUI and, at the same time, keeping the Win95 cursor intact. Mono blits no longer cause transparency issues in some programs (e.g.: Creative utilities such as MIDI and CD on Win3.1x). --- src/include/86box/vid_xga.h | 2 +- src/video/vid_xga.c | 144 ++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 866aea4a3..f60b3359b 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -92,7 +92,7 @@ typedef struct xga_t { int on; int op_mode_reset, linear_endian_reverse; int sprite_pos, sprite_pos_prefetch, cursor_data_on; - int pal_test; + int pal_test, a5_test; int type, bus; uint32_t linear_base, linear_size, banked_mask; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 2941d9cb2..4a141660b 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -73,6 +73,8 @@ linear: } xga->on = 0; vga_on = 1; + if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test) + xga->linear_endian_reverse = 1; } else { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); @@ -320,8 +322,18 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 0; } } - if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) - xga->cursor_data_on = 0; + + if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) { + if (xga->aperture_cntl) { + if (xga->sprite_pos & 0x0f) + xga->cursor_data_on = 1; + else + xga->cursor_data_on = 0; + } else { + xga->cursor_data_on = 0; + } + } + //pclog("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); break; case 0x62: @@ -716,7 +728,7 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b xga_t *xga = &svga->xga; uint32_t addr = base; int bits; - uint32_t byte, byte2; + uint32_t byte; uint8_t px; int skip = 0; @@ -735,7 +747,6 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) if (xga->linear_endian_reverse) bits = 7 - (x & 7); @@ -744,18 +755,18 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b else { bits = 7 - (x & 7); } - px = (byte2 >> bits) & 1; + px = (byte >> bits) & 1; return px; } static uint32_t -xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, int height) +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) { xga_t *xga = &svga->xga; uint32_t addr = base; int bits; - uint32_t byte, byte2; + uint32_t byte; uint8_t px; int skip = 0; @@ -776,7 +787,6 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) if (xga->linear_endian_reverse) bits = 7 - (x & 7); @@ -785,7 +795,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int else { bits = 7 - (x & 7); } - px = (byte2 >> bits) & 1; + px = (byte >> bits) & 1; return px; case 3: /*8-bit*/ addr += (y * width); @@ -819,12 +829,11 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } static void -xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width, int height) +xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width) { xga_t *xga = &svga->xga; uint32_t addr = base; uint8_t byte, mask; - uint8_t byte2; int skip = 0; if (xga->base_addr_1mb) { @@ -844,7 +853,6 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { if (xga->linear_endian_reverse) mask = 1 << (7 - (x & 7)); @@ -853,11 +861,19 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { mask = 1 << (7 - (x & 7)); } - byte2 = (byte2 & ~mask) | ((pixel ? 0xff : 0) & mask); - if (!skip) { - WRITE(addr, byte2); + byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); + if (pixel & 1) { + if (!skip) { + xga->vram[((addr)) & (xga->vram_mask)] |= mask; + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + } + } else { + if (!skip) { + xga->vram[((addr)) & (xga->vram_mask)] &= ~mask; + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + } } - mem_writeb_phys(addr, byte2); + mem_writeb_phys(addr, byte); break; case 3: /*8-bit*/ addr += (y * width); @@ -947,8 +963,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) if (xga->accel.command & 0xc0) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -962,19 +978,19 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -988,13 +1004,13 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } else if (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } @@ -1080,8 +1096,8 @@ xga_line_draw_write(svga_t *svga) if (steep) { if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1094,18 +1110,18 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } else { if ((dy >= xga->accel.mask_map_origin_x_off) && (dy <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dx >= xga->accel.mask_map_origin_y_off) && (dx <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1118,18 +1134,18 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } } else { if (steep) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1142,15 +1158,15 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1163,11 +1179,11 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } @@ -1267,8 +1283,8 @@ xga_bitblt(svga_t *svga) if (xga->accel.command & 0xc0) { if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1280,12 +1296,12 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1297,7 +1313,7 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } @@ -1361,11 +1377,11 @@ xga_bitblt(svga_t *svga) if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.bkgd_color; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1377,16 +1393,16 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { if (mix) - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.frgd_color; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.bkgd_color; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1398,7 +1414,7 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } @@ -1827,7 +1843,7 @@ exec_command: xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); //if (xga->accel.pat_src) { - // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x\n", + // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x, planemask = %08x\n", // CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], // xga->accel.px_map_width[xga->accel.dst_map], xga->accel.px_map_width[xga->accel.src_map], // xga->accel.px_map_height[xga->accel.pat_src], xga->accel.px_map_height[xga->accel.dst_map], @@ -1837,8 +1853,8 @@ exec_command: // xga->accel.src_map_x, xga->accel.src_map_y, // xga->accel.pat_src, xga->accel.dst_map, xga->accel.src_map, // xga->accel.px_map_base[xga->accel.dst_map], xga->accel.px_map_base[xga->accel.src_map], xga->accel.px_map_base[xga->accel.pat_src], - // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f); - // pclog("\n"); + // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); + // //pclog("\n"); //} switch ((xga->accel.command >> 24) & 0x0f) { case 3: /*Bresenham Line Draw Read*/ @@ -2681,6 +2697,8 @@ static void xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; xga->bios_rom.sz = 0x2000; + xga->linear_endian_reverse = 0; + xga->a5_test = 0; f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); From 43952325ba4aecd91be2e5a4d05ce1507c99b45c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Aug 2022 23:21:56 +0200 Subject: [PATCH 31/33] Fixed initialized 8-bit blits for OS/2 2.0 Limited Availability (6H.177) and other builds before GA/RTM. --- src/video/vid_svga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index ea70248dc..9ab96c169 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1079,6 +1079,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ svga->xga.test = val; + svga->xga.a5_test = 1; return; } else if (val == 0x5a) { svga->xga.test = val; From 8c8a42a9be0c2476fa1cd3c3c33a73644d60db89 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Aug 2022 23:27:03 +0200 Subject: [PATCH 32/33] ESDI MCA: No longer fatal on default reads, fixes Win3.0 MME installation to hard disk using ESDI MCA. --- src/disk/hdc_esdi_mca.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 72db74359..6f6b77723 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -863,7 +863,8 @@ esdi_read(uint16_t port, void *priv) break; default: - fatal("esdi_read port=%04x\n", port); + esdi_mca_log("esdi_read port=%04x\n", port); + break; } return (ret); From 2ebee217b542ec007df7caa48b7f28e89eeff69e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 10 Aug 2022 11:10:54 +0600 Subject: [PATCH 33/33] qt_d3d9renderer: Clear screen backbuffer at each render --- src/qt/qt_d3d9renderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index 96718a4a2..b4269d2e7 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -108,6 +108,7 @@ void D3D9Renderer::paintEvent(QPaintEvent *event) dstRect.left = destination.left(); dstRect.right = destination.right(); d3d9dev->BeginScene(); + d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); while (surfaceInUse) {} surfaceInUse = true; d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR);