From 0faca6ae49d3d2eca7f6c951fb9953df2c712c8c Mon Sep 17 00:00:00 2001 From: Robert de Rooy Date: Fri, 5 Aug 2022 18:22:03 +0200 Subject: [PATCH 01/36] 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 02/36] 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 03/36] 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 04/36] 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 05/36] 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 06/36] 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 07/36] 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 08/36] 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 09/36] 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 10/36] 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 11/36] 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 12/36] 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 13/36] 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 14/36] 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 15/36] 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 16/36] 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 17/36] 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 18/36] 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 19/36] 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 20/36] 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 21/36] 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 22/36] 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); From 740108c37c84f22ae2cca1c8145d85a12b2de2b0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 11 Aug 2022 01:13:49 +0600 Subject: [PATCH 23/36] cdrom: Properly empty the path of image if it can't be loaded --- src/cdrom/cdrom_image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 9a653b310..f8f7536e6 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -257,6 +257,7 @@ image_open_abort(cdrom_t *dev) cdrom_image_close(dev); dev->ops = NULL; dev->host_drive = 0; + dev->image_path[0] = 0; return 1; } From 97242168ded8a5f1fbd289512056961952784d15 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 11 Aug 2022 01:16:56 +0600 Subject: [PATCH 24/36] qt: Fix usage of unconverted path in plat_fopen64 UTF-8 paths are not supported on all Windows installations, only some of them. This was only accounted for in the 32-bit plat_fopen function, not on 64-bit plat_fopen64. Fix that oversight. --- src/qt/qt_platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 8aa85fb9c..8a41769a9 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -167,7 +167,7 @@ plat_fopen(const char *path, const char *mode) FILE * plat_fopen64(const char *path, const char *mode) { - return fopen(path, mode); + return fopen(QString::fromUtf8(path).toLocal8Bit(), mode); } int From ee38432bb7d8a4d30bdb3c0d8adc14409be3a5ba Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Aug 2022 22:44:08 +0200 Subject: [PATCH 25/36] Added some parentheses. --- src/qt/qt_renderercommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index bb4903ee8..0b8108b00 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 && video_fullscreen_scale_maximized ? (parentWidget->isMaximized() == false && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1) { + 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; } From f2cf5dd841d97aae615cc277947e39523915d7ff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 12 Aug 2022 00:35:40 +0600 Subject: [PATCH 26/36] qt: Restore Xinput2 for Qt5 builds --- src/qt/qt_rendererstack.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 3ff223ce4..d7ff5214b 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -75,8 +75,15 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) { if (QApplication::platformName().contains("wayland")) strcpy(auto_mouse_type, "wayland"); +# if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + else if (QApplication::platformName() == "eglfs") + strcpy(auto_mouse_type, "evdev"); + else if (QApplication::platformName() == "xcb") + strcpy(auto_mouse_type, "xinput2"); +# else else if (QApplication::platformName() == "eglfs" || QApplication::platformName() == "xcb") strcpy(auto_mouse_type, "evdev"); +# endif else auto_mouse_type[0] = '\0'; mouse_type = auto_mouse_type; @@ -96,6 +103,14 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) this->mouse_poll_func = evdev_mouse_poll; } # endif + if (!stricmp(mouse_type, "xinput2")) { + extern void xinput2_init(); + extern void xinput2_poll(); + extern void xinput2_exit(); + xinput2_init(); + this->mouse_poll_func = xinput2_poll; + this->mouse_exit_func = xinput2_exit; + } #endif #ifdef __APPLE__ this->mouse_poll_func = macos_poll_mouse; From ad3bba009a8b52ccd53c9e71d428812d537c1fad Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 12 Aug 2022 13:24:29 +0600 Subject: [PATCH 27/36] qt: Raise minimum Xi2 version requirement to 2.1 This is needed for click-and-drag to work with both Qt5 and Qt6, especially the latter which was previously broken, without any hacks. --- src/qt/qt_rendererstack.cpp | 5 ----- src/qt/xinput2_mouse.cpp | 5 ++--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index d7ff5214b..c5ae2b423 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -75,15 +75,10 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) { if (QApplication::platformName().contains("wayland")) strcpy(auto_mouse_type, "wayland"); -# if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) else if (QApplication::platformName() == "eglfs") strcpy(auto_mouse_type, "evdev"); else if (QApplication::platformName() == "xcb") strcpy(auto_mouse_type, "xinput2"); -# else - else if (QApplication::platformName() == "eglfs" || QApplication::platformName() == "xcb") - strcpy(auto_mouse_type, "evdev"); -# endif else auto_mouse_type[0] = '\0'; mouse_type = auto_mouse_type; diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index 07791b5ba..b1887bedc 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -81,8 +81,7 @@ void xinput2_proc() Window win; win = DefaultRootWindow(disp); - // XIAllMasterDevices doesn't work for click-and-drag operations. - ximask.deviceid = XIAllDevices; + ximask.deviceid = XIAllMasterDevices; ximask.mask_len = XIMaskLen(XI_LASTEVENT); ximask.mask = (unsigned char*)calloc(ximask.mask_len, sizeof(unsigned char)); @@ -166,7 +165,7 @@ void xinput2_init() qWarning() << "Cannot open current X11 display"; return; } - auto event = 0, err = 0, minor = 0, major = 2; + auto event = 0, err = 0, minor = 1, major = 2; if (XQueryExtension(disp, "XInputExtension", &xi2opcode, &event, &err)) { if (XIQueryVersion(disp, &major, &minor) == Success) From 3194130bcdb118cbc7d9f06adc4a6154e03be1af Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 12 Aug 2022 14:33:15 +0600 Subject: [PATCH 28/36] qt: large sizes when entered no longer decrement by 1MB --- src/qt/qt_harddiskdialog.cpp | 5 +++++ src/qt/qt_harddiskdialog.hpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 91179cdbc..3040db9c3 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -39,6 +39,7 @@ extern "C" { #include #include #include +#include #include "qt_harddrive_common.hpp" #include "qt_settings_bus_tracking.hpp" @@ -608,6 +609,7 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { } void HarddiskDialog::recalcSize() { + if (disallowSizeModifications) return; uint64_t size = (static_cast(cylinders_) * static_cast(heads_) * static_cast(sectors_)) << 9; ui->lineEditSize->setText(QString::number(size >> 20)); } @@ -731,6 +733,7 @@ void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { } void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { + disallowSizeModifications = true; uint32_t size = text.toUInt(); /* This is needed to ensure VHD standard compliance. */ hdd_image_calc_chs(&cylinders_, &heads_, §ors_, size); @@ -742,6 +745,8 @@ void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { checkAndAdjustCylinders(); checkAndAdjustHeads(); checkAndAdjustSectors(); + + disallowSizeModifications = false; } void HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) { diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index 408726f63..f876d35dd 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -49,6 +49,8 @@ private: uint32_t max_sectors = 0; uint32_t max_heads = 0; uint32_t max_cylinders = 0; + + bool disallowSizeModifications = false; bool checkAndAdjustCylinders(); bool checkAndAdjustHeads(); From 9d5c73101704ba55542acb3a220ee2b3611c054d Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 12 Aug 2022 18:50:17 +0200 Subject: [PATCH 29/36] Kasan VGA fix. --- src/video/vid_et4000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index c18a422a3..76e609ee0 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -728,7 +728,7 @@ et4000_init(const device_t *info) et4000_kasan_recalctimings, et4000_in, et4000_out, NULL, NULL); io_sethandler(0x03c0, 32, - et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev); + et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); io_sethandler(0x0250, 8, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); io_sethandler(0x0258, 2, From a85caea4a9f2294a3b85ea9f0f8675c80c9b4ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Fri, 12 Aug 2022 18:59:46 +0200 Subject: [PATCH 30/36] Update qt_harddiskdialog.cpp Removed the stray QTimer include. --- src/qt/qt_harddiskdialog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 3040db9c3..c5ced345f 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -39,7 +39,6 @@ extern "C" { #include #include #include -#include #include "qt_harddrive_common.hpp" #include "qt_settings_bus_tracking.hpp" From 603cdcbb375023aa35c8d4b0145fb04578b540e7 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Fri, 12 Aug 2022 00:39:33 +0500 Subject: [PATCH 31/36] Clear unfilled registers when returning CPUID results on K6-2/III/+ CPUs --- src/cpu/cpu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 36d92605f..3ec257674 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1742,9 +1742,11 @@ cpu_CPUID(void) break; case 0x80000000: EAX = 0x80000005; + EBX = ECX = EDX = 0; break; case 0x80000001: EAX = CPUID + 0x100; + EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ @@ -1760,6 +1762,7 @@ cpu_CPUID(void) EDX = 0x00000000; break; case 0x80000005: /*Cache information*/ + EAX = 0; EBX = 0x02800140; /*TLBs*/ ECX = 0x20020220; /*L1 data cache*/ EDX = 0x20020220; /*L1 instruction cache*/ @@ -1785,9 +1788,11 @@ cpu_CPUID(void) break; case 0x80000000: EAX = 0x80000006; + EBX = ECX = EDX = 0; break; case 0x80000001: EAX = CPUID + 0x100; + EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ @@ -1803,11 +1808,13 @@ cpu_CPUID(void) EDX = 0x00000000; break; case 0x80000005: /* Cache information */ + EAX = 0; EBX = 0x02800140; /* TLBs */ ECX = 0x20020220; /*L1 data cache*/ EDX = 0x20020220; /*L1 instruction cache*/ break; case 0x80000006: /* L2 Cache information */ + EAX = EBX = EDX = 0; ECX = 0x01004220; break; default: @@ -1832,9 +1839,11 @@ cpu_CPUID(void) break; case 0x80000000: EAX = 0x80000007; + EBX = ECX = EDX = 0; break; case 0x80000001: EAX = CPUID + 0x100; + EBX = ECX = 0; EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW; break; case 0x80000002: /* Processor name string */ @@ -1850,17 +1859,20 @@ cpu_CPUID(void) EDX = 0x00000000; break; case 0x80000005: /* Cache information */ + EAX = 0; EBX = 0x02800140; /* TLBs */ ECX = 0x20020220; /* L1 data cache */ EDX = 0x20020220; /* L1 instruction cache */ break; case 0x80000006: /* L2 Cache information */ + EAX = EBX = EDX = 0; if (cpu_s->cpu_type == CPU_K6_3P) ECX = 0x01004220; else ECX = 0x00804220; break; case 0x80000007: /* PowerNow information */ + EAX = EBX = ECX = 0; EDX = 7; break; default: From 94f76ef3c0aa1ec4f7ee4230d4ca6cda77fae7d9 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 4 Jul 2022 16:45:17 +0500 Subject: [PATCH 32/36] Fix some warnings in Qt code --- src/qt/qt_openglrenderer.cpp | 2 +- src/qt/qt_openglrenderer.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 115e6af7f..b3e771fea 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -254,7 +254,7 @@ OpenGLRenderer::initializeExtensions() glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress(context->hasExtension("GL_EXT_buffer_storage") ? "glBufferStorageEXT" : "glBufferStorage"); if (!glBufferStorage) - glBufferStorage = glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress("glBufferStorage"); + glBufferStorage = (PFNGLBUFFERSTORAGEEXTPROC_LOCAL) context->getProcAddress("glBufferStorage"); } #endif } diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index da64ea79b..99393c30d 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -77,8 +77,8 @@ private: static constexpr int BUFFERBYTES = 16777216; /* Pixel is 4 bytes. */ static constexpr int BUFFERCOUNT = 3; /* How many buffers to use for pixel transfer (2-3 is commonly recommended). */ - OpenGLOptions *options; QTimer *renderTimer; + OpenGLOptions *options; QString glslVersion; From 789e2c950ffe0f05ecba826b87886a7371c2421e Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Sun, 17 Oct 2021 03:21:27 +0500 Subject: [PATCH 33/36] Remove the PS/2 mouse flag from the Gigabyte GA-586IP --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index eaeed3e6b..4a41b6ef1 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -7389,7 +7389,7 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 1.5 }, - .bus_flags = MACHINE_PS2_PCI, + .bus_flags = MACHINE_PCI, .flags = MACHINE_IDE_DUAL, .ram = { .min = 2048, From bd31c57d60eebd4405bdc74a68a743c435aa04bb Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Sat, 13 Aug 2022 23:16:44 +0200 Subject: [PATCH 34/36] Fix SB 2.0 OPL crash --- src/sound/snd_sb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index fb2332fbd..1431365ad 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1654,16 +1654,16 @@ sb_2_init(const device_t *info) io_sethandler(addr, 0x0002, sb->opl.read, NULL, NULL, sb->opl.write, NULL, NULL, - sb->opl.write); + sb->opl.priv); } io_sethandler(addr + 8, 0x0002, sb->opl.read, NULL, NULL, sb->opl.write, NULL, NULL, - sb->opl.write); + sb->opl.priv); io_sethandler(0x0388, 0x0002, sb->opl.read, NULL, NULL, sb->opl.write, NULL, NULL, - sb->opl.write); + sb->opl.priv); } if (sb->cms_enabled) { From 012db280e2706e277a1f22503b83189a144c60cb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Aug 2022 12:28:36 +0600 Subject: [PATCH 35/36] qt: Remember maximized state of monitor windows if enabled --- src/config.c | 15 +++++++++++++-- src/include/86box/video.h | 1 + src/qt/qt_main.cpp | 8 +++++++- src/qt/qt_mainwindow.cpp | 7 +++++++ src/qt/qt_rendererstack.cpp | 8 ++++++++ src/qt/qt_rendererstack.hpp | 1 + 6 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index 768bbe3e4..79fd7433b 100644 --- a/src/config.c +++ b/src/config.c @@ -649,10 +649,14 @@ load_monitor(int monitor_index) if (p == NULL) p = temp; - if (window_remember) + if (window_remember) { sscanf(p, "%i, %i, %i, %i", &monitor_settings[monitor_index].mon_window_x, &monitor_settings[monitor_index].mon_window_y, &monitor_settings[monitor_index].mon_window_w, &monitor_settings[monitor_index].mon_window_h); + monitor_settings[monitor_index].mon_window_maximized = !!config_get_int(cat, "window_maximized", 0); + } else { + monitor_settings[monitor_index].mon_window_maximized = 0; + } } /* Load "Machine" section. */ @@ -2415,8 +2419,15 @@ save_monitor(int monitor_index) monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h); config_set_string(cat, "window_coordinates", temp); - } else + if (monitor_settings[monitor_index].mon_window_maximized != 0) { + config_set_int(cat, "window_maximized", monitor_settings[monitor_index].mon_window_maximized); + } else { + config_delete_var(cat, "window_maximized"); + } + } else { config_delete_var(cat, "window_coordinates"); + config_delete_var(cat, "window_maximized"); + } } /* Save "Machine" section. */ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 85c95c98d..34cc2cb81 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -124,6 +124,7 @@ typedef struct monitor_settings_t { int mon_window_y; int mon_window_w; int mon_window_h; + int mon_window_maximized; } monitor_settings_t; #define MONITORS_NUM 2 diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 694a0e5f6..de2fef1bd 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -173,6 +173,7 @@ int main(int argc, char* argv[]) { return 0; } + bool startMaximized = window_remember && monitor_settings[0].mon_window_maximized; fprintf(stderr, "Qt: version %s, platform \"%s\"\n", qVersion(), QApplication::platformName().toUtf8().data()); ProgSettings::loadTranslators(&app); #ifdef Q_OS_WINDOWS @@ -200,7 +201,12 @@ int main(int argc, char* argv[]) { discord_load(); main_window = new MainWindow(); - main_window->show(); + if (startMaximized) { + main_window->showMaximized(); + } else { + main_window->show(); + } + app.installEventFilter(main_window); #ifdef Q_OS_WINDOWS diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index c19dc4f54..0ee5a3161 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -657,6 +657,9 @@ void MainWindow::initRendererMonitorSlot(int monitor_index) monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } + if (monitor_settings[monitor_index].mon_window_maximized) { + secondaryRenderer->showMaximized(); + } secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api); } @@ -2070,6 +2073,10 @@ void MainWindow::changeEvent(QEvent* event) } #endif QWidget::changeEvent(event); + if (isVisible()) { + monitor_settings[0].mon_window_maximized = isMaximized(); + config_save(); + } } void MainWindow::on_actionRenderer_options_triggered() diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index c5ae2b423..6beb37516 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -48,6 +48,7 @@ extern "C" { #include <86box/86box.h> +#include <86box/config.h> #include <86box/mouse.h> #include <86box/plat.h> #include <86box/video.h> @@ -481,3 +482,10 @@ void RendererStack::closeEvent(QCloseEvent* event) main_window->close(); } +void RendererStack::changeEvent(QEvent *event) +{ + if (m_monitor_index != 0 && isVisible()) { + monitor_settings[m_monitor_index].mon_window_maximized = isMaximized(); + config_save(); + } +} diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index b2eccc84a..4d06ed1cf 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -32,6 +32,7 @@ public: void wheelEvent(QWheelEvent *event) override; void leaveEvent(QEvent *event) override; void closeEvent(QCloseEvent *event) override; + void changeEvent(QEvent* event) override; void resizeEvent(QResizeEvent *event) override { onResize(event->size().width(), event->size().height()); From ee651ae48ffbaafd6e507604185143e3dbda69ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Sun, 14 Aug 2022 20:47:36 +0200 Subject: [PATCH 36/36] Update x86_ops_bcd.h Reverted the AAM instruction to again set the divisor to 10 when 0 is specified. --- src/cpu/x86_ops_bcd.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index efb0de264..385d63cd7 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -31,14 +31,7 @@ static int opAAD(uint32_t fetchdat) 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; setznp16(AX);