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/(ops = NULL; dev->host_drive = 0; + dev->image_path[0] = 0; return 1; } diff --git a/src/config.c b/src/config.c index 2a2f58c6c..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. */ @@ -969,6 +973,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"; @@ -2413,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. */ @@ -2554,6 +2567,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/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; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 9248fe4ad..7ff81607f 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: diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index b37b6a6df..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); 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 } 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); 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/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/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/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/include/86box/video.h b/src/include/86box/video.h index 8661fcef8..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 @@ -133,6 +134,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/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: 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, diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 120f4572c..5ad252f1a 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,39 @@ 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) { + while (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(); } diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index e7ef16f77..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); @@ -145,6 +146,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 +166,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_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 91179cdbc..c5ced345f 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -608,6 +608,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 +732,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 +744,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(); 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_main.cpp b/src/qt/qt_main.cpp index a74958511..de2fef1bd 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_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 /* Every 200 frames we save the machine status. */ if (++frames >= 200 && nvr_dosave) { qt_nvr_save(); @@ -161,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 @@ -188,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 f05c32ba6..0ee5a3161 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 @@ -132,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) @@ -292,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. */ @@ -653,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); } @@ -1772,11 +1779,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(); } @@ -2062,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() @@ -2122,3 +2137,26 @@ 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/"))); +} + + +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 c33decb44..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); @@ -129,10 +131,13 @@ protected: private slots: void on_actionShow_non_primary_monitors_triggered(); + 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 522d2f081..3551eddb1 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -91,6 +91,8 @@ + + @@ -177,6 +179,7 @@ + @@ -778,6 +781,19 @@ 6 + + + 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 3a5f58846..b3e771fea 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 @@ -95,8 +97,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 +181,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()); @@ -252,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 } @@ -425,6 +427,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); 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; 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 diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 0974c1f78..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) { + 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..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> @@ -75,8 +76,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"); - else if (QApplication::platformName() == "eglfs" || QApplication::platformName() == "xcb") + else if (QApplication::platformName() == "eglfs") strcpy(auto_mouse_type, "evdev"); + else if (QApplication::platformName() == "xcb") + strcpy(auto_mouse_type, "xinput2"); else auto_mouse_type[0] = '\0'; mouse_type = auto_mouse_type; @@ -96,6 +99,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; @@ -397,6 +408,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"); @@ -470,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 75cabec49..4d06ed1cf 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -32,6 +32,11 @@ 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()); + } void keyPressEvent(QKeyEvent *event) override { event->ignore(); 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: 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() 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) 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) { 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. */ diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index d5fe0a0b1..585e1aa17 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,6 +12,8 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* +%global romver v3.7 + Name: 86Box Version: 3.7.1 Release: 1%{?dist} @@ -20,7 +22,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/%{romver}.zip BuildRequires: cmake BuildRequires: desktop-file-utils @@ -55,7 +57,7 @@ It supports various models of PCs, graphics and sound cards, and CPUs. %package roms Summary: ROMs for use with 86Box -Version: %{version} +Version: %{romver} License: Proprietary BuildArch: noarch @@ -111,7 +113,7 @@ popd # files part of the rom package %files roms -%license roms-%{version}/LICENSE +%license roms-%{romver}/LICENSE %{_datadir}/%{name}/roms %changelog 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, 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; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 17b4c4981..3a8c4b10a 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -43,35 +43,33 @@ 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; + 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]; + uint32_t line_width = (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); + memset(line_ptr, 0, line_width); } @@ -81,13 +79,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; } @@ -97,14 +96,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; } 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);