From 57349bedd368f4d93a9785fc4f637af5baf30d75 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 2 Nov 2025 00:48:57 +0100 Subject: [PATCH 01/21] Make the % fraction-less again. --- src/86box.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/86box.c b/src/86box.c index 52ca8a774..8b2dddc7f 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1740,19 +1740,19 @@ update_mouse_msg(void) *(wcp - 1) = L'\0'; mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i.%%i%%%% - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); wcsncpy(mouse_msg[2], L"%i.%i%%", sizeof_w(mouse_msg[2])); #else - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls", + swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif } @@ -1887,7 +1887,7 @@ pc_run(void) else fps = ((fps + 20) / 50) * 50; #endif - swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10)); + swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); From 79614f6ada271954b2131919f183023ecc1e969e Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 2 Nov 2025 00:52:20 +0100 Subject: [PATCH 02/21] Swap the XGA 4bpp rendering nibbles for proper display. Fixes incorrect rendering of XGA 4bpp accelerated modes (INMOS XGA ISA and XGA MCA add-ons) --- src/video/vid_xga.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 0a9822006..bec538c62 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2716,15 +2716,15 @@ xga_hwcursor_draw(svga_t *svga, int displine) if (x >= idx) { switch (comb) { case 0x00: - /* Cursor Color 1 */ + /* Cursor Color 1 */ p[x_pos] = xga->hwc_color0; break; case 0x01: - /* Cursor Color 2 */ + /* Cursor Color 2 */ p[x_pos] = xga->hwc_color1; break; case 0x03: - /* Complement */ + /* Complement */ p[x_pos] ^= 0xffffff; break; @@ -2793,24 +2793,24 @@ xga_render_4bpp(svga_t *svga) for (int x = 0; x <= xga->h_disp; x += 16) { dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]); - p[1] = xga->pallook[dat & 0x0f]; - p[0] = xga->pallook[(dat >> 4) & 0x0f]; - p[3] = xga->pallook[(dat >> 8) & 0x0f]; - p[2] = xga->pallook[(dat >> 12) & 0x0f]; - p[5] = xga->pallook[(dat >> 16) & 0x0f]; - p[4] = xga->pallook[(dat >> 20) & 0x0f]; - p[7] = xga->pallook[(dat >> 24) & 0x0f]; - p[6] = xga->pallook[(dat >> 28) & 0x0f]; + p[0] = xga->pallook[dat & 0x0f]; + p[1] = xga->pallook[(dat >> 4) & 0x0f]; + p[2] = xga->pallook[(dat >> 8) & 0x0f]; + p[3] = xga->pallook[(dat >> 12) & 0x0f]; + p[4] = xga->pallook[(dat >> 16) & 0x0f]; + p[5] = xga->pallook[(dat >> 20) & 0x0f]; + p[6] = xga->pallook[(dat >> 24) & 0x0f]; + p[7] = xga->pallook[(dat >> 28) & 0x0f]; dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]); - p[9] = xga->pallook[dat & 0x0f]; - p[8] = xga->pallook[(dat >> 4) & 0x0f]; - p[11] = xga->pallook[(dat >> 8) & 0x0f]; - p[10] = xga->pallook[(dat >> 12) & 0x0f]; - p[13] = xga->pallook[(dat >> 16) & 0x0f]; - p[12] = xga->pallook[(dat >> 20) & 0x0f]; - p[15] = xga->pallook[(dat >> 24) & 0x0f]; - p[14] = xga->pallook[(dat >> 28) & 0x0f]; + p[8] = xga->pallook[dat & 0x0f]; + p[9] = xga->pallook[(dat >> 4) & 0x0f]; + p[10] = xga->pallook[(dat >> 8) & 0x0f]; + p[11] = xga->pallook[(dat >> 12) & 0x0f]; + p[12] = xga->pallook[(dat >> 16) & 0x0f]; + p[13] = xga->pallook[(dat >> 20) & 0x0f]; + p[14] = xga->pallook[(dat >> 24) & 0x0f]; + p[15] = xga->pallook[(dat >> 28) & 0x0f]; xga->memaddr += 8; p += 16; From 30743b6dfd5a6f16599c3c149b279b4a9265143b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 2 Nov 2025 03:51:47 +0100 Subject: [PATCH 03/21] Tandy warning fix from pixel_jupiter. --- src/video/vid_tandy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_tandy.c b/src/video/vid_tandy.c index 3d2be3a41..0130fb7be 100644 --- a/src/video/vid_tandy.c +++ b/src/video/vid_tandy.c @@ -478,7 +478,7 @@ vid_render(tandy_t *dev, int line, int hos_offs) } else if (out_x > -8) { for (c = -out_x; c < 8; c++) { buffer32->line[line][out_x + c] = - vid->array[((dat >> 12 - (c >> 1) * 4) & vid->array[1] & 0x0f) + 16] + 16; + vid->array[((dat >> (12 - (c >> 1) * 4)) & vid->array[1] & 0x0f) + 16] + 16; } } } @@ -508,7 +508,7 @@ vid_render(tandy_t *dev, int line, int hos_offs) } else if (out_x > -16) { for (c = -out_x; c < 16; c++) { buffer32->line[line][out_x + c] = - vid->array[((dat >> 12 - (c >> 2) * 4) & vid->array[1] & 0x0f) + 16] + 16; + vid->array[((dat >> (12 - (c >> 2) * 4)) & vid->array[1] & 0x0f) + 16] + 16; } } } From 75b1a94929765e2ed0c14735c5e2dec5842edeef Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 4 Nov 2025 00:28:56 +0600 Subject: [PATCH 04/21] Fix dirty block checking on NDR for byte-masked blocks --- src/cpu/386_dynarec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 23f3f1e35..41a61495e 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -405,7 +405,7 @@ exec386_dynarec_dyn(void) uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); # ifdef USE_NEW_DYNAREC int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ULL << (PAGE_BYTE_MASK_MASK & 0x3f); + uint64_t byte_mask = 1ULL << (phys_addr & PAGE_BYTE_MASK_MASK); if ((page->code_present_mask & mask) || ((page->mem != page_ff) && (page->byte_code_present_mask[byte_offset] & byte_mask))) From c490e3e14ce67fb8249251d9bff9e1a727003386 Mon Sep 17 00:00:00 2001 From: pixel-jupiter <180155003+pixel-jupiter@users.noreply.github.com> Date: Tue, 4 Nov 2025 07:43:51 +0300 Subject: [PATCH 05/21] PCjr: Fix inverted horizontal screen movement --- src/video/vid_pcjr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index fe982980c..d9259d53a 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -269,7 +269,7 @@ vid_get_h_overscan_delta(pcjr_t *pcjr) break; } - ret = pcjr->crtc[0x02] - def; + ret = def - pcjr->crtc[0x02]; if (ret < -8) ret = -8; From c00a82c58c380a6f721243e421fedd2fc213fdbc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 4 Nov 2025 17:03:27 +0600 Subject: [PATCH 06/21] Reapply "Merge pull request #6172 from Cacodemon345/armfixes-2" This reverts commit 5577efe301aa8babdc32602470b2b73b0c7bbc4d. --- src/codegen_new/codegen_backend_arm64_ops.c | 28 ++++++++++++++++-- src/codegen_new/codegen_backend_arm64_ops.h | 3 ++ src/codegen_new/codegen_backend_arm64_uops.c | 29 ++++++++++--------- src/codegen_new/codegen_backend_x86-64_uops.c | 12 ++++---- src/codegen_new/codegen_ir.c | 1 + src/codegen_new/codegen_ir_defs.h | 4 +-- src/codegen_new/codegen_ops.c | 26 ++++------------- src/codegen_new/codegen_ops_helpers.h | 4 +++ src/codegen_new/codegen_reg.c | 2 +- 9 files changed, 64 insertions(+), 45 deletions(-) diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 915cae93d..9d5806edf 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -102,6 +102,10 @@ # define OPCODE_SUB_LSR (0x25a << 21) # define OPCODE_SUBX_LSL (0x658 << 21) +# define OPCODE_INS_B (0x6e010400) +# define OPCODE_INS_H (0x6e020400) +# define OPCODE_INS_S (0x6e040400) +# define OPCODE_INS_D (0x6e080400) # define OPCODE_ADD_V8B (0x0e208400) # define OPCODE_ADD_V4H (0x0e608400) # define OPCODE_ADD_V2S (0x0ea08400) @@ -180,6 +184,7 @@ # define OPCODE_SQSUB_V8B (0x0e202c00) # define OPCODE_SQSUB_V4H (0x0e602c00) # define OPCODE_SQXTN_V8B_8H (0x0e214800) +# define OPCODE_SQXTUN_V8B_8H (0x2e212800) # define OPCODE_SQXTN_V4H_4S (0x0e614800) # define OPCODE_SHL_VD (0x0f005400) # define OPCODE_SHL_VQ (0x4f005400) @@ -207,6 +212,7 @@ # define OPCODE_ZIP1_V8B (0x0e003800) # define OPCODE_ZIP1_V4H (0x0e403800) # define OPCODE_ZIP1_V2S (0x0e803800) +# define OPCODE_ZIP1_V2D (0x4ec03800) # define OPCODE_ZIP2_V8B (0x0e007800) # define OPCODE_ZIP2_V4H (0x0e407800) # define OPCODE_ZIP2_V2S (0x0e807800) @@ -225,11 +231,11 @@ # define IMM_LOGICAL(imm) ((imm) << 10) -# define BIT_TBxZ(bit) ((((bit) &0x1f) << 19) | (((bit) &0x20) ? (1 << 31) : 0)) +# define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) # define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) # define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) &0x1fffff) >> 2) << 5)) +# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) # define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) # define OFFSET12_B(offset) (offset << 10) @@ -716,6 +722,12 @@ host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } +void +host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index) +{ + codegen_addlong(block, OPCODE_INS_D | Rd(dst_reg) | Rn(src_reg) | ((dst_index & 1) << 20) | ((src_index & 1) << 14)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { @@ -1225,6 +1237,13 @@ host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } + +void +host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SQXTUN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { @@ -1475,6 +1494,11 @@ host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_re codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } void +host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP1_V2D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index df751b4aa..129c2b2a3 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -72,6 +72,7 @@ void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element); +void host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index); void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); @@ -184,6 +185,7 @@ void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); @@ -243,6 +245,7 @@ void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 2bb6281ff..d06685cb2 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -801,7 +801,8 @@ codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); - host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 1); + host_arm64_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); return 0; } @@ -849,28 +850,28 @@ codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG0, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG1, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG2, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG3, uop->imm_data); return 0; } @@ -1448,9 +1449,9 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); + host_arm64_SQXTN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1465,9 +1466,9 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); + host_arm64_SQXTN_V4H_4S(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1480,9 +1481,9 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); + host_arm64_SQXTUN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 356c8bcde..6b206d5b5 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -220,9 +220,9 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); # else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); # endif host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); @@ -906,9 +906,9 @@ static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); # else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); # endif return 0; } @@ -916,9 +916,9 @@ static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RDX, uop->imm_data); # else - host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RSI, uop->imm_data); # endif return 0; } diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index d14fa0f23..dfd136289 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -53,6 +53,7 @@ duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) new_uop->imm_data = uop->imm_data; new_uop->p = uop->p; new_uop->pc = uop->pc; + new_uop->is_a16 = uop->is_a16; if (uop->jump_dest_uop != -1) { new_uop->jump_dest_uop = uop->jump_dest_uop + offset; diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 60f7badea..bfc19373b 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -336,7 +336,7 @@ typedef struct uop_t { ir_reg_t src_reg_a; ir_reg_t src_reg_b; ir_reg_t src_reg_c; - uint32_t imm_data; + uintptr_t imm_data; void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; @@ -601,7 +601,7 @@ uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_re } static inline void -uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uintptr_t imm) { uop_t *uop = uop_alloc(ir, uop_type); diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index bb7d1f3ee..68861ff52 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -86,13 +86,8 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, -#endif /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -100,13 +95,11 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif @@ -119,13 +112,8 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, -#endif /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -133,13 +121,11 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif // clang-format on diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 92b721099..05928bd2f 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,6 +114,10 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { + /* TODO: Re-enable this again after fixing mysterious crashes on ARM64 with MMX instructions used. */ +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 + return 0; +#endif if (block->flags & CODEBLOCK_BYTE_MASK) return 0; diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index f91377df8..b678bd6ac 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -201,7 +201,7 @@ static const uint8_t native_requested_sizes[9][8] = [REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, [REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, - [REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1 + [REG_POINTER][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1 }; void From 93d478691fb8992a3e3ea0f86a7ed644b36b7922 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 4 Nov 2025 17:05:16 +0600 Subject: [PATCH 07/21] Second take on fixing ARM64 MMX opcodes --- src/codegen_new/codegen_ir_defs.h | 15 +++++++++++---- src/codegen_new/codegen_ops_helpers.h | 4 ---- src/cpu/386_dynarec.c | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index bfc19373b..da404e49e 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -660,6 +660,9 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr uop->p = p; } +extern int codegen_mmx_enter(void); +extern int codegen_fp_enter(void); + #define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) @@ -726,15 +729,19 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr #define uop_FP_ENTER(ir) \ do { \ - if (!codegen_fpu_entered) \ - uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); \ + if (!codegen_fpu_entered) { \ + uop_CALL_FUNC_RESULT(ir, IREG_temp0, codegen_fp_enter); \ + uop_CMP_IMM_JZ(ir, IREG_temp0, 1, codegen_exit_rout); \ + } \ codegen_fpu_entered = 1; \ codegen_mmx_entered = 0; \ } while (0) #define uop_MMX_ENTER(ir) \ do { \ - if (!codegen_mmx_entered) \ - uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); \ + if (!codegen_mmx_entered) { \ + uop_CALL_FUNC_RESULT(ir, IREG_temp0, codegen_mmx_enter); \ + uop_CMP_IMM_JZ(ir, IREG_temp0, 1, codegen_exit_rout); \ + } \ codegen_mmx_entered = 1; \ codegen_fpu_entered = 0; \ } while (0) diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 05928bd2f..92b721099 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,10 +114,6 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - /* TODO: Re-enable this again after fixing mysterious crashes on ARM64 with MMX instructions used. */ -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 - return 0; -#endif if (block->flags & CODEBLOCK_BYTE_MASK) return 0; diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 41a61495e..ff729e4cf 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -242,6 +242,20 @@ static uint64_t tsc_old = 0; int32_t acycs = 0; # endif +int +codegen_mmx_enter(void) +{ + MMX_ENTER(); + return 0; +} + +int +codegen_fp_enter(void) +{ + FP_ENTER(); + return 0; +} + void update_tsc(void) { From 3749b25c830972ec46470757390123cedbb004e1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 4 Nov 2025 19:11:55 +0100 Subject: [PATCH 08/21] Revert the x64 changes. --- src/codegen_new/codegen_backend_x86-64_uops.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 6b206d5b5..356c8bcde 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -220,9 +220,9 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); # else - host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); # endif host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); @@ -906,9 +906,9 @@ static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); # else - host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); # endif return 0; } @@ -916,9 +916,9 @@ static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV64_REG_IMM(block, REG_RDX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); # else - host_x86_MOV64_REG_IMM(block, REG_RSI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); # endif return 0; } From 98bb4950f84aece7c86778fd587ee301a629184f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 4 Nov 2025 19:17:00 +0100 Subject: [PATCH 09/21] Revert back to the old code on x64. --- src/codegen_new/codegen_ir.c | 2 ++ src/codegen_new/codegen_ir_defs.h | 25 +++++++++++++++++++++++++ src/codegen_new/codegen_reg.c | 4 ++++ 3 files changed, 31 insertions(+) diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index dfd136289..7c34a69e5 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -53,7 +53,9 @@ duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) new_uop->imm_data = uop->imm_data; new_uop->p = uop->p; new_uop->pc = uop->pc; +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 new_uop->is_a16 = uop->is_a16; +#endif if (uop->jump_dest_uop != -1) { new_uop->jump_dest_uop = uop->jump_dest_uop + offset; diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index da404e49e..88923b5bf 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -336,7 +336,11 @@ typedef struct uop_t { ir_reg_t src_reg_a; ir_reg_t src_reg_b; ir_reg_t src_reg_c; +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 uintptr_t imm_data; +#else + uint32_t imm_data; +#endif void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; @@ -601,7 +605,11 @@ uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_re } static inline void +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uintptr_t imm) +#else +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +#endif { uop_t *uop = uop_alloc(ir, uop_type); @@ -727,6 +735,7 @@ extern int codegen_fp_enter(void); #define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) #define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 #define uop_FP_ENTER(ir) \ do { \ if (!codegen_fpu_entered) { \ @@ -745,6 +754,22 @@ extern int codegen_fp_enter(void); codegen_mmx_entered = 1; \ codegen_fpu_entered = 0; \ } while (0) +#else +#define uop_FP_ENTER(ir) \ + do { \ + if (!codegen_fpu_entered) \ + uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); \ + codegen_fpu_entered = 1; \ + codegen_mmx_entered = 0; \ + } while (0) +#define uop_MMX_ENTER(ir) \ + do { \ + if (!codegen_mmx_entered) \ + uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); \ + codegen_mmx_entered = 1; \ + codegen_fpu_entered = 0; \ + } while (0) +#endif #define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) #define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index b678bd6ac..234cfe3a2 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -201,7 +201,11 @@ static const uint8_t native_requested_sizes[9][8] = [REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, [REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 [REG_POINTER][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1 +#else + [REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1 +#endif }; void From 215c5719ad5e4572cbf43b62cb4642112945047a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 5 Nov 2025 00:30:11 +0600 Subject: [PATCH 10/21] Add some stuff that got missed in ARM64 NDR changes --- src/codegen_new/codegen_ir_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 88923b5bf..bec1607e0 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -739,6 +739,7 @@ extern int codegen_fp_enter(void); #define uop_FP_ENTER(ir) \ do { \ if (!codegen_fpu_entered) { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ uop_CALL_FUNC_RESULT(ir, IREG_temp0, codegen_fp_enter); \ uop_CMP_IMM_JZ(ir, IREG_temp0, 1, codegen_exit_rout); \ } \ @@ -748,6 +749,7 @@ extern int codegen_fp_enter(void); #define uop_MMX_ENTER(ir) \ do { \ if (!codegen_mmx_entered) { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ uop_CALL_FUNC_RESULT(ir, IREG_temp0, codegen_mmx_enter); \ uop_CMP_IMM_JZ(ir, IREG_temp0, 1, codegen_exit_rout); \ } \ From daf34f3dcd77c01bc348041af5abc5fe9ca83616 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 02:54:51 +0100 Subject: [PATCH 11/21] (S)VGA: Bring back specific pel panning behavior for some ATi and Tseng graphics cards, closes #6437. --- src/video/vid_ati_mach64.c | 2 + src/video/vid_et4000w32.c | 1 + src/video/vid_svga.c | 96 ++++++++++++++++++++++++++++---------- 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 95a32dabe..e464ec7a5 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -5027,6 +5027,7 @@ mach64vt_init(const device_t *info) mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; + svga->adv_flags |= FLAG_PANNING_ATI; return mach64; } @@ -5058,6 +5059,7 @@ mach64vt2_init(const device_t *info) mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; + svga->adv_flags |= FLAG_PANNING_ATI; return mach64; } diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index cd78c555e..54154fb93 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2966,6 +2966,7 @@ et4000w32p_init(const device_t *info) et4000->pci_regs[0x33] = 0xf0; et4000->svga.packed_chain4 = 1; + et4000->svga.adv_flags |= FLAG_PANNING_ATI; return et4000; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 03f829e74..af15fe178 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1421,6 +1421,41 @@ svga_poll(void *priv) } else { timer_advance_u64(&svga->timer, svga->dispontime); + if (svga->adv_flags & FLAG_PANNING_ATI) { + if (svga->panning_blank) { + svga->scrollcache = 0; + svga->half_pixel = 0; + + svga->x_add = svga->left_overscan; + } else { + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) + svga->scrollcache &= 0x07; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + svga->half_pixel = 0; + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; + svga->scrollcache &= 0x07; + } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; + svga->half_pixel = svga->scrollcache & 0x01; + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } + + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; + + svga->x_add = svga->left_overscan - svga->scrollcache; + } + } + if (svga->dispon) svga->cgastat &= ~1; svga->hdisp_on = 0; @@ -1477,9 +1512,13 @@ svga_poll(void *priv) svga->scanline = 0; if (svga->attrregs[0x10] & 0x20) { - svga->scrollcache = 0; - svga->half_pixel = 0; - svga->x_add = svga->left_overscan; + if (svga->adv_flags & FLAG_PANNING_ATI) + svga->panning_blank = 1; + else { + svga->scrollcache = 0; + svga->half_pixel = 0; + svga->x_add = svga->left_overscan; + } } } } @@ -1570,32 +1609,39 @@ svga_poll(void *priv) svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - svga->scrollcache = (svga->attrregs[0x13] & 0x0f); - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 1) - svga->scrollcache &= 0x07; - else { - svga->scrollcache++; - if (svga->scrollcache > 8) - svga->scrollcache = 0; - } + if ((svga->adv_flags & FLAG_PANNING_ATI) && svga->panning_blank) { + svga->scrollcache = 0; svga->half_pixel = 0; - } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || - (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { - svga->half_pixel = 0; - svga->scrollcache &= 0x07; + + svga->x_add = svga->left_overscan; } else { - if (svga->scrollcache > 7) - svga->scrollcache = 7; - svga->half_pixel = svga->scrollcache & 0x01; - svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) + svga->scrollcache &= 0x07; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + svga->half_pixel = 0; + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; + svga->scrollcache &= 0x07; + } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; + svga->half_pixel = svga->scrollcache & 0x01; + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } + + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; + + svga->x_add = svga->left_overscan - svga->scrollcache; } - if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) - svga->scrollcache <<= 1; - - svga->x_add = svga->left_overscan - svga->scrollcache; - svga->linecountff = 0; svga->hwcursor_on = 0; From f81c293485a509d4abec4871baa3167d5a5de163 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 03:04:49 +0100 Subject: [PATCH 12/21] And I forgot a missing fraction (and vid_svga.h). --- src/86box.c | 2 +- src/include/86box/vid_svga.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index 8b2dddc7f..fae30ca5e 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1744,7 +1744,7 @@ update_mouse_msg(void) plat_get_string(STRING_MOUSE_CAPTURE)); swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - wcsncpy(mouse_msg[2], L"%i.%i%%", sizeof_w(mouse_msg[2])); + wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #else swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 814a986c3..252463af7 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -29,6 +29,7 @@ # define FLAG_512K_MASK 512 # define FLAG_NO_SHIFT3 1024 /* Needed for Bochs VBE. */ # define FLAG_PRECISETIME 2048 /* Needed for Copper demo if on dynarec. */ +# define FLAG_PANNING_ATI 4096 struct monitor_t; typedef struct hwcursor_t { @@ -136,6 +137,7 @@ typedef struct svga_t { int ps_bit_bug; int ati_4color; int vblankend; + int panning_blank; int render_line_offset; int start_retrace_latch; int vga_mode; From 872ad63c1265ed7ec755e60683be8da496d1108a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 04:11:37 +0100 Subject: [PATCH 13/21] PC87306 Super I/O chip fixes, fixes #6428. --- src/sio/sio_pc87306.c | 172 ++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 105 deletions(-) diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index f9e066b1f..38e695727 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -38,6 +38,7 @@ typedef struct pc87306_t { uint8_t tries; + uint8_t cfg_lock; uint8_t regs[29]; uint8_t gpio[2]; uint16_t gpioba; @@ -125,6 +126,7 @@ lpt_handler(pc87306_t *dev) uint8_t lpt_irq = LPT2_IRQ; uint8_t cnfgb_readout = 0x08; + pclog("Removing LPT port...\n"); lpt_port_remove(dev->lpt); temp = dev->regs[0x01] & 3; @@ -155,6 +157,9 @@ lpt_handler(pc87306_t *dev) break; } + if (!(dev->regs[0x00] & 0x01)) + lpt_port = 0x000; + if (dev->regs[0x1b] & 0x10) lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5; @@ -167,8 +172,10 @@ lpt_handler(pc87306_t *dev) lpt_set_epp(dev->lpt, !!(dev->regs[0x04] & 0x01)); lpt_set_ecp(dev->lpt, !!(dev->regs[0x04] & 0x04)); - if (lpt_port) + if (lpt_port) { + pclog("Setting up LPT port at %04X...\n", lpt_port); lpt_port_setup(dev->lpt, lpt_port); + } lpt_port_irq(dev->lpt, lpt_irq); @@ -187,18 +194,20 @@ serial_handler(pc87306_t *dev, int uart) uint8_t pnp_shift; uint8_t irq; - temp = (dev->regs[0x01] >> (2 << uart)) & 3; + serial_remove(dev->uart[uart]); fer_shift = 2 << uart; /* 2 for UART 1, 4 for UART 2 */ pnp_shift = 2 + (uart << 2); /* 2 for UART 1, 6 for UART 2 */ + temp = (dev->regs[0x01] >> fer_shift) & 3; + /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ fer_irq = ((dev->regs[1] >> fer_shift) & 1) ? 3 : 4; pnp1_irq = ((dev->regs[0x1c] >> pnp_shift) & 1) ? 4 : 3; irq = (dev->regs[0x1c] & 1) ? pnp1_irq : fer_irq; - switch (temp) { + if (dev->regs[0x00] & fer_shift) switch (temp) { case 0: serial_setup(dev->uart[uart], COM1_ADDR, irq); break; @@ -273,13 +282,15 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) return; } else { if (dev->tries) { - if ((dev->cur_reg == 0) && (val == 8)) - val = 0x4b; + if (dev->cfg_lock) + return; + valxor = val ^ dev->regs[dev->cur_reg]; dev->tries = 0; - if ((dev->cur_reg <= 28) && (dev->cur_reg != 8)) { - if (dev->cur_reg == 0) - val &= 0x5f; + if ((dev->cur_reg <= 0x1c) && (dev->cur_reg != 0x08)) { + if ((dev->cur_reg == 0x00) && (val == 0x08)) + val = 0x4f; + dev->regs[dev->cur_reg] = val; } else return; @@ -291,21 +302,12 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0x00: - if (valxor & 0x01) { - lpt_port_remove(dev->lpt); - if ((val & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } - if (valxor & 0x02) { - serial_remove(dev->uart[0x00]); - if ((val & 2) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 0); - } - if (valxor & 0x04) { - serial_remove(dev->uart[0x01]); - if ((val & 4) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 1); - } + if (valxor & 0x01) + lpt_handler(dev); + if (valxor & 0x02) + serial_handler(dev, 0); + if (valxor & 0x04) + serial_handler(dev, 1); if (valxor & 0x28) { fdc_remove(dev->fdc); if ((val & 8) && !(dev->regs[0x02] & 1)) @@ -313,52 +315,24 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } break; case 0x01: - if (valxor & 0x03) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } - if (valxor & 0xcc) { - serial_remove(dev->uart[0x00]); - if ((dev->regs[0x00] & 2) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 0); - } - if (valxor & 0xf0) { - serial_remove(dev->uart[0x01]); - if ((dev->regs[0x00] & 4) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 1); - } + if (valxor & 0x03) + lpt_handler(dev); + if (valxor & 0xcc) + serial_handler(dev, 0); + if (valxor & 0xf0) + serial_handler(dev, 1); break; case 0x02: - if (valxor & 0x01) { - lpt_port_remove(dev->lpt); - serial_remove(dev->uart[0x00]); - serial_remove(dev->uart[0x01]); - fdc_remove(dev->fdc); - - if (!(val & 1)) { - if (dev->regs[0x00] & 0x01) - lpt_handler(dev); - if (dev->regs[0x00] & 0x02) - serial_handler(dev, 0); - if (dev->regs[0x00] & 0x04) - serial_handler(dev, 1); - if (dev->regs[0x00] & 0x08) - fdc_set_base(dev->fdc, (dev->regs[0x00] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); - } - } - if (valxor & 0x88) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } + if (valxor & 0x01) + fdc_set_power_down(dev->fdc, val & 0x01); + if (valxor & 0x40) + dev->cfg_lock = val & 0x40; + if (valxor & 0x88) + lpt_handler(dev); break; case 0x04: - if (valxor & (0x05)) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) - lpt_handler(dev); - } + if (valxor & (0x05)) + lpt_handler(dev); if (valxor & 0x80) nvr_lock_set(0x00, 256, !!(val & 0x80), dev->nvr); break; @@ -389,37 +363,24 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) pc87306_gpio_handler(dev); break; case 0x18: - if (valxor & (0x0e)) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) - lpt_handler(dev); - } + if (valxor & (0x0e)) + lpt_handler(dev); break; case 0x19: - if (valxor) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } + if (valxor) + lpt_handler(dev); break; case 0x1b: if (valxor & 0x70) { - lpt_port_remove(dev->lpt); if (!(val & 0x40)) dev->regs[0x19] = 0xef; - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); + lpt_handler(dev); } break; case 0x1c: if (valxor) { - serial_remove(dev->uart[0x00]); - serial_remove(dev->uart[0x01]); - - if ((dev->regs[0x00] & 2) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 0); - if ((dev->regs[0x00] & 4) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 1); + serial_handler(dev, 0); + serial_handler(dev, 1); } break; @@ -437,15 +398,17 @@ pc87306_read(uint16_t port, void *priv) index = (port & 1) ? 0 : 1; - if (dev->tries == 0xff) { - ret = 0x88; - dev->tries = 0xfe; - } else if (dev->tries == 0xfe) { - ret = 0x00; - dev->tries = 0; - } else if (index) { - ret = dev->cur_reg & 0x1f; - dev->tries = 0; + if (index) { + if (dev->tries == 0xff) { + ret = 0x88; + dev->tries = 0xfe; + } else if (dev->tries == 0xfe) { + ret = 0x00; + dev->tries = 0; + } else { + ret = dev->cur_reg & 0x1f; + dev->tries = 0; + } } else { if (dev->cur_reg == 8) ret = 0x70; @@ -462,30 +425,27 @@ pc87306_reset_common(void *priv) { pc87306_t *dev = (pc87306_t *) priv; - memset(dev->regs, 0, 29); - + memset(dev->regs, 0x00, 29); dev->tries = 0xff; - dev->regs[0x00] = 0x0B; - dev->regs[0x01] = 0x01; + dev->regs[0x00] = 0x00; + dev->regs[0x01] = 0x10; + dev->regs[0x02] = 0x08; dev->regs[0x03] = 0x01; - dev->regs[0x05] = 0x0D; + dev->regs[0x05] = 0x0d; dev->regs[0x08] = 0x70; - dev->regs[0x09] = 0xC0; + dev->regs[0x09] = 0xc0; dev->regs[0x0b] = 0x80; - dev->regs[0x0f] = 0x1E; + dev->regs[0x0f] = 0x1e; dev->regs[0x12] = 0x30; - dev->regs[0x19] = 0xEF; + dev->regs[0x19] = 0xef; /* 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ lpt_set_cnfga_readout(dev->lpt, 0x10); - lpt_port_remove(dev->lpt); lpt_handler(dev); - serial_remove(dev->uart[0x00]); - serial_remove(dev->uart[0x01]); serial_handler(dev, 0); serial_handler(dev, 1); fdc_reset(dev->fdc); @@ -495,6 +455,8 @@ pc87306_reset_common(void *priv) nvr_at_handler(1, 0x0070, dev->nvr); nvr_bank_set(0, 0, dev->nvr); nvr_wp_set(0, 0, dev->nvr); + + dev->cfg_lock = 0; } void From e0a3509a119169af65e3b1cdca862252c515b09f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 04:12:50 +0100 Subject: [PATCH 14/21] PC87306: Remove some excess logging. --- src/sio/sio_pc87306.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index 38e695727..d347048bb 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -126,7 +126,6 @@ lpt_handler(pc87306_t *dev) uint8_t lpt_irq = LPT2_IRQ; uint8_t cnfgb_readout = 0x08; - pclog("Removing LPT port...\n"); lpt_port_remove(dev->lpt); temp = dev->regs[0x01] & 3; @@ -172,10 +171,8 @@ lpt_handler(pc87306_t *dev) lpt_set_epp(dev->lpt, !!(dev->regs[0x04] & 0x01)); lpt_set_ecp(dev->lpt, !!(dev->regs[0x04] & 0x04)); - if (lpt_port) { - pclog("Setting up LPT port at %04X...\n", lpt_port); + if (lpt_port) lpt_port_setup(dev->lpt, lpt_port); - } lpt_port_irq(dev->lpt, lpt_irq); From 6e4b62d24f2060b43d317cb1f7b3050b217d6a7c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 06:03:59 +0100 Subject: [PATCH 15/21] PC87306: More fixes. --- src/sio/sio_pc87306.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index d347048bb..5b9cafa37 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -425,12 +425,12 @@ pc87306_reset_common(void *priv) memset(dev->regs, 0x00, 29); dev->tries = 0xff; - dev->regs[0x00] = 0x00; - dev->regs[0x01] = 0x10; + dev->regs[0x00] = 0x0b; + dev->regs[0x01] = 0x01; dev->regs[0x02] = 0x08; dev->regs[0x03] = 0x01; dev->regs[0x05] = 0x0d; - dev->regs[0x08] = 0x70; + dev->regs[0x08] = 0x71; dev->regs[0x09] = 0xc0; dev->regs[0x0b] = 0x80; dev->regs[0x0f] = 0x1e; From 031c382c3eca5427436433875f51f9fabc143599 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 06:12:09 +0100 Subject: [PATCH 16/21] PC87306: Properly fix the ID readout, now it works on the Thor & Co. even without the register 0x00 hack. --- src/sio/sio_pc87306.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index 5b9cafa37..7fdf6d2d6 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -284,12 +284,9 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) valxor = val ^ dev->regs[dev->cur_reg]; dev->tries = 0; - if ((dev->cur_reg <= 0x1c) && (dev->cur_reg != 0x08)) { - if ((dev->cur_reg == 0x00) && (val == 0x08)) - val = 0x4f; - + if ((dev->cur_reg <= 0x1c) && (dev->cur_reg != 0x08)) dev->regs[dev->cur_reg] = val; - } else + else return; } else { dev->tries++; @@ -407,8 +404,8 @@ pc87306_read(uint16_t port, void *priv) dev->tries = 0; } } else { - if (dev->cur_reg == 8) - ret = 0x70; + if (dev->cur_reg == 0x08) + ret = 0x71; else if (dev->cur_reg < 28) ret = dev->regs[dev->cur_reg]; dev->tries = 0; @@ -427,7 +424,6 @@ pc87306_reset_common(void *priv) dev->regs[0x00] = 0x0b; dev->regs[0x01] = 0x01; - dev->regs[0x02] = 0x08; dev->regs[0x03] = 0x01; dev->regs[0x05] = 0x0d; dev->regs[0x08] = 0x71; From 33bca0521c366921a329ab80962ffbff8184418c Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Wed, 5 Nov 2025 17:52:15 +0800 Subject: [PATCH 17/21] new machine: Thomson TO16 --- src/include/86box/machine.h | 4 ++ src/machine/m_xt.c | 100 ++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 43 ++++++++++++++++ 3 files changed, 147 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 628e388e8..11992f764 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1446,6 +1446,10 @@ extern int machine_xt_pb8810_init(const machine_t *); extern int machine_xt_sansx16_init(const machine_t *); extern int machine_xt_pcxt_init(const machine_t *); #ifdef EMU_DEVICE_H +extern const device_t to16_device; +#endif +extern int machine_xt_to16_init(const machine_t *); +#ifdef EMU_DEVICE_H extern const device_t vendex_device; #endif extern int machine_xt_vendex_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 007e8c7c4..f0b5d37a6 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -1704,6 +1704,106 @@ machine_xt_pcxt_init(const machine_t *model) return ret; } +static const device_config_t to16_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "to16", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "1.03", + .internal_name = "to16", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { "roms/machines/to16/TO16_103.bin", "" } + }, + { .files_no = 0 } + }, + }, + { + .name = "rtc_port", + .description = "Onboard RTC", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Uninstalled", .value = 0 }, + { .description = "RTC0", .value = 0x300 }, + { .description = "RTC1", .value = 0x2c0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "rtc_irq", + .description = "RTC IRQ2", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "Enabled", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t to16_device = { + .name = "Thomson TO16", + .internal_name = "to16_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = to16_config +}; + +int +machine_xt_to16_init(const machine_t *model) +{ + int ret = 0; + int rtc_port = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + rtc_port = machine_get_config_int("rtc_port"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000f8000, 32768, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + machine_xt_clone_init(model, 0); + + if (rtc_port != 0) + device_add(&rtc58167_device); + + return ret; +} + static const device_config_t vendex_config[] = { // clang-format off { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index bd68734c7..72806d9d8 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1784,6 +1784,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] Thomson TO16", + .internal_name = "to16", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_to16_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 768, + .step = 64 + }, + .nvrmask = 0, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_xtclone_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &to16_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Toshiba T1000", .internal_name = "t1000", From 138929caec75ecd0ee528b87639fedf178cd9c1c Mon Sep 17 00:00:00 2001 From: Vitaly Orekhov Date: Wed, 5 Nov 2025 15:59:43 +0300 Subject: [PATCH 18/21] 8514/A: Fix first NVRAM initialization on MCA bus version made by ATI Prior to this change it was not possible to start the emulated machine with this graphics adapter installed on any operating system different from Windows, causing crash with exit code 11. --- src/video/vid_ati_eeprom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 84cbffedb..3f9d707ca 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -56,7 +56,6 @@ ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn, int mca) size = 128; if (!fp) { if (mca) { - (void) fseek(fp, 2L, SEEK_SET); memset(eeprom->data + 2, 0xff, size - 2); fp = nvr_fopen(eeprom->fn, "wb"); fwrite(eeprom->data, 1, size, fp); From 3dc3cfc00de58b6f3ffb03973de4cd1825ea66ba Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 15:03:32 +0100 Subject: [PATCH 19/21] ATi Mach8 EEPROM: Remove superfluous (and emulator-crashing!) fseek(). --- src/video/vid_ati_eeprom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 84cbffedb..8baa72351 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -54,9 +54,8 @@ ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn, int mca) strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); fp = nvr_fopen(eeprom->fn, "rb"); size = 128; - if (!fp) { + if (fp == NULL) { if (mca) { - (void) fseek(fp, 2L, SEEK_SET); memset(eeprom->data + 2, 0xff, size - 2); fp = nvr_fopen(eeprom->fn, "wb"); fwrite(eeprom->data, 1, size, fp); From 6afc72b86038ff2b6fadb8a8f78169ee69f5123a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 17:36:54 +0100 Subject: [PATCH 20/21] IBM PS/ValuePoint 433: Fix on-board ET4000/W32. --- src/machine/m_at_socket2.c | 12 +++++++++++- src/video/vid_et4000w32.c | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/machine/m_at_socket2.c b/src/machine/m_at_socket2.c index b7cf93d92..8ea151f53 100644 --- a/src/machine/m_at_socket2.c +++ b/src/machine/m_at_socket2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #define HAVE_STDARG_H @@ -333,11 +334,13 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 int ret; ret = bios_load_linear("roms/machines/valuepoint433/$IMAGEP.FLH", - 0x000e0000, 131072, 0); + 0x000c0000, 262144, 0); if (bios_only || !ret) return ret; + memcpy(&rom[0x00020000], rom, 131072); + machine_at_common_ide_init(model); device_add(&sis_85c461_device); if (gfxcard[0] == VID_INTERNAL) @@ -350,6 +353,13 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); + if (gfxcard[0] != VID_INTERNAL) { + for (uint16_t i = 0; i < 32768; i++) + rom[i] = mem_readb_phys(0x000c0000 + i); + } + mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); + mem_mapping_set_exec(&bios_mapping, rom); + return ret; } diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 54154fb93..c0d802fe4 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2825,8 +2825,9 @@ et4000w32p_init(const device_t *info) et4000->rev = ET4000W32; et4000->ramdac_type = ET4K_SDAC; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32_MACHSPEED_VGA_GUI_2400S, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + if (!(info->local & 0x100)) + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32_MACHSPEED_VGA_GUI_2400S, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; From ae5a34d31cada09eddab437e89d97410b3b8508b Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 5 Nov 2025 17:39:55 +0100 Subject: [PATCH 21/21] VIA Apollo: Fix all the improper VT8601 checks. --- src/chipset/via_apollo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 974f4e274..3236bbbbe 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -348,7 +348,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x58: - if ((dev->id >= VIA_585) || (dev->id < VIA_597) || (dev->id == VIA_597) || ((dev->id >= VIA_693A) || (dev->id < VIA_8601))) + if ((dev->id >= VIA_585) || (dev->id < VIA_597) || (dev->id == VIA_597) || ((dev->id >= VIA_693A) && (dev->id < VIA_8601))) dev->pci_conf[0x58] = (dev->pci_conf[0x58] & ~0xee) | (val & 0xee); else dev->pci_conf[0x58] = val; @@ -501,14 +501,14 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x69: if ((dev->id != VIA_585) || (dev->id != VIA_595)) { - if ((dev->id == VIA_693A) || (dev->id < VIA_8601)) + if ((dev->id == VIA_693A) && (dev->id < VIA_8601)) dev->pci_conf[0x69] = (dev->pci_conf[0x69] & ~0xfe) | (val & 0xfe); else dev->pci_conf[0x69] = val; } break; case 0x6b: - if ((dev->id == VIA_693A) || (dev->id < VIA_8601)) + if ((dev->id == VIA_693A) && (dev->id < VIA_8601)) dev->pci_conf[0x6b] = val; else if (dev->id == VIA_691) dev->pci_conf[0x6b] = (dev->pci_conf[0x6b] & ~0xcf) | (val & 0xcf); @@ -520,7 +520,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0x6b] = (dev->pci_conf[0x6b] & ~0xc1) | (val & 0xc1); break; case 0x6c: - if ((dev->id == VIA_597) || ((dev->id == VIA_693A) || (dev->id < VIA_8601))) + if ((dev->id == VIA_597) || ((dev->id == VIA_693A) && (dev->id < VIA_8601))) dev->pci_conf[0x6c] = (dev->pci_conf[0x6c] & ~0x1f) | (val & 0x1f); else if (dev->id == VIA_598) dev->pci_conf[0x6c] = (dev->pci_conf[0x6c] & ~0x7f) | (val & 0x7f);