From ecd67950d460d7d525763e6a1254e83e7a1b3b1a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 14:03:42 +0100 Subject: [PATCH 001/146] SCSI CD-ROM Toshiba fixes. Data track is not audio, fixes anything that wants to play data track as audio. --- src/cdrom/cdrom.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 40686f14a90..c5755709d09 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -614,8 +614,14 @@ cdrom_audio_track_search(cdrom_t *dev, uint32_t pos, int type, uint8_t playbit) break; } - /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) - the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; @@ -641,6 +647,14 @@ cdrom_audio_track_search_pioneer(cdrom_t *dev, uint32_t pos, uint8_t playbit) dev->seek_pos = pos; + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + dev->cd_buflen = 0; dev->cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED; return 1; @@ -705,8 +719,14 @@ cdrom_audio_play_toshiba(cdrom_t *dev, uint32_t pos, int type) cdrom_log("Toshiba/NEC Play Audio: MSF = %06x, type = %02x, cdstatus = %02x\n", pos, type, dev->cd_status); - /* Unlike standard commands, if there's a data track on an Audio CD (mixed mode) - the playback continues with the audio muted (Toshiba CD-ROM SCSI-2 manual reference). */ + /* Do this at this point, since it's at this point that we know the + actual LBA position to start playing from. */ + if (!(dev->ops->track_type(dev, pos) & CD_TRACK_AUDIO)) { + cdrom_log("CD-ROM %i: LBA %08X not on an audio track\n", dev->id, pos); + cdrom_stop(dev); + return 0; + } + dev->cd_buflen = 0; dev->cd_status = CD_STATUS_PLAYING; return 1; From e4696aa2e96f9a05fb87bd79646c35a914c74bbb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 20:17:55 +0100 Subject: [PATCH 002/146] Undev branch the Matrox Millennium since it is now mostly usable. --- src/include/86box/video.h | 2 +- src/video/CMakeLists.txt | 7 +- src/video/vid_mga.c | 228 ++++++++++++++++++++++++++------------ src/video/vid_table.c | 4 +- 4 files changed, 160 insertions(+), 81 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 1858fc24679..0d435fd369c 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -431,9 +431,9 @@ extern const device_t ht216_32_standalone_device; extern const device_t im1024_device; extern const device_t pgc_device; -# if defined(DEV_BRANCH) && defined(USE_MGA) /* Matrox MGA */ extern const device_t millennium_device; +# if defined(DEV_BRANCH) extern const device_t mystique_device; extern const device_t mystique_220_device; # endif diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 59205f235cb..638837757ae 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -25,14 +25,9 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c - vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_nga.c + vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(MGA) - target_compile_definitions(vid PRIVATE USE_MGA) - target_sources(vid PRIVATE vid_mga.c) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 74bb9d07ae8..86b3c3a921f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -856,23 +856,23 @@ mystique_recalctimings(svga_t *svga) svga->clock = (cpuclock * (float) (1ULL << 32)) / svga->getclock(clk_sel & 3, svga->clock_gen); if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) - svga->htotal += 0x100; + svga->htotal |= 0x100; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) - svga->vtotal += 0x400; + svga->vtotal |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) - svga->vtotal += 0x800; + svga->vtotal |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) - svga->dispend += 0x400; + svga->dispend |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) - svga->vblankstart += 0x400; + svga->vblankstart |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) - svga->vblankstart += 0x800; + svga->vblankstart |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) - svga->vsyncstart += 0x400; + svga->vsyncstart |= 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) - svga->vsyncstart += 0x800; + svga->vsyncstart |= 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) - svga->split += 0x400; + svga->split |= 0x400; if (mystique->type == MGA_2064W) tvp3026_recalctimings(svga->ramdac, svga); @@ -935,7 +935,7 @@ mystique_recalctimings(svga_t *svga) } else { switch (svga->bpp) { case 8: - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_incompatible_highres; break; case 15: svga->render = svga_render_15bpp_highres; @@ -949,9 +949,6 @@ mystique_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; break; - - default: - break; } } svga->line_compare = mystique_line_compare; @@ -1381,7 +1378,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) svga_t *svga = &mystique->svga; uint8_t ret = 0xff; int fifocount; - uint16_t addr_0x0f = 0; + uint8_t addr_0x0f = 0; uint16_t addr_0x03 = 0; int rs2 = 0; int rs3 = 0; @@ -1944,7 +1941,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; svga_t *svga = &mystique->svga; - uint16_t addr_0x0f = 0; + uint8_t addr_0x0f = 0; uint16_t addr_0x03 = 0; int rs2 = 0; int rs3 = 0; @@ -3944,7 +3941,7 @@ z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl } static void -blit_line(mystique_t *mystique, UNUSED(int closed)) +blit_line(mystique_t *mystique, int closed) { svga_t *svga = &mystique->svga; uint32_t src; @@ -3952,48 +3949,104 @@ blit_line(mystique_t *mystique, UNUSED(int closed)) uint32_t old_dst; int x; int z_write; + int pattern; + int funcnt = mystique->dwgreg.funcnt; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { + while (mystique->dwgreg.length >= 0) { + pattern = mystique->dwgreg.src[0] & (1 << funcnt); + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + if (closed) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + } break; case MACCESS_PWIDTH_16: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + if (closed) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + } break; case MACCESS_PWIDTH_24: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + if (closed) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } break; case MACCESS_PWIDTH_32: - src = mystique->dwgreg.fcol; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) + src = mystique->dwgreg.fcol; + else { + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (pattern) + src = mystique->dwgreg.fcol; + } else + src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + } dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + if (closed) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } else if (!closed && mystique->dwgreg.length > 0) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + } break; default: @@ -4016,6 +4069,9 @@ blit_line(mystique_t *mystique, UNUSED(int closed)) mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; mystique->dwgreg.length--; + funcnt = (funcnt - 1) & mystique->dwgreg.stylelen; + if (mystique->dwgreg.length == 0xffff) + break; } break; @@ -4186,25 +4242,25 @@ blit_trap(mystique_t *mystique) fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; } - if ((int32_t) mystique->dwgreg.ar[1] < 0) { - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t) mystique->dwgreg.ar[4] < 0) { - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4266,25 +4322,25 @@ blit_trap(mystique_t *mystique) fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } } - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; } - if ((int32_t) mystique->dwgreg.ar[1] < 0) { - while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t) mystique->dwgreg.ar[4] < 0) { - while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -4367,7 +4423,11 @@ blit_trap(mystique_t *mystique) mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; } @@ -4403,7 +4463,10 @@ blit_trap(mystique_t *mystique) break; default: - fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#if 0 + pclog("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); +#endif + break; } mystique->blitter_complete_refcount++; @@ -4615,7 +4678,11 @@ blit_texture_trap(mystique_t *mystique) } } skip_pixel: - x_l++; + if (x_l > x_r) + x_l--; + else + x_l++; + mystique->pixel_count++; mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; @@ -4747,9 +4814,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4854,9 +4926,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -4937,9 +5014,14 @@ blit_bitblt(mystique_t *mystique) } else src_addr += x_dir; - if (x != x_end) - x += x_dir; - else + if (x != x_end) { + if ((x > x_end) && (x_dir == 1)) + x--; + else if ((x < x_end) && (x_dir == -1)) + x++; + else + x += x_dir; + } else break; } @@ -5024,7 +5106,9 @@ blit_idump(mystique_t *mystique) mystique->dwgreg.iload_rem_data = 0; mystique->dwgreg.idump_end_of_line = 0; mystique->busy = 1; - /* pclog("IDUMP ATYPE RPL busy\n"); */ +#if 0 + pclog("IDUMP ATYPE RPL busy\n"); +#endif break; default: diff --git a/src/video/vid_table.c b/src/video/vid_table.c index b4198eefd22..04d48c9d989 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -204,8 +204,8 @@ video_cards[] = { { &s3_virge_357_pci_device }, { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA) - { &millennium_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &millennium_device }, +#if defined(DEV_BRANCH) { &mystique_device }, { &mystique_220_device }, #endif From 1df37c2440e2675efd4454f4e72b88f051bdafa4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 20:21:57 +0100 Subject: [PATCH 003/146] Temporarily added the older 8bpp highres render for the Matrox Millennium. --- src/include/86box/vid_svga_render.h | 1 + src/video/vid_svga_render.c | 83 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/include/86box/vid_svga_render.h b/src/include/86box/vid_svga_render.h index bc6894ca98e..33bb13bbf40 100644 --- a/src/include/86box/vid_svga_render.h +++ b/src/include/86box/vid_svga_render.h @@ -53,6 +53,7 @@ extern void svga_render_4bpp_lowres(svga_t *svga); extern void svga_render_4bpp_highres(svga_t *svga); extern void svga_render_8bpp_lowres(svga_t *svga); extern void svga_render_8bpp_highres(svga_t *svga); +extern void svga_render_8bpp_incompatible_highres(svga_t *svga); extern void svga_render_8bpp_tseng_lowres(svga_t *svga); extern void svga_render_8bpp_tseng_highres(svga_t *svga); extern void svga_render_8bpp_gs_lowres(svga_t *svga); diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 7cc0aafc388..f7bc36130d9 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -665,6 +665,89 @@ void svga_render_4bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true void svga_render_8bpp_lowres(svga_t *svga) { svga_render_indexed_gfx(svga, false, true); } void svga_render_8bpp_highres(svga_t *svga) { svga_render_indexed_gfx(svga, true, true); } +void +svga_render_8bpp_incompatible_highres(svga_t *svga) +{ + int x; + uint32_t *p; + uint32_t dat; + uint32_t changed_addr; + uint32_t addr; + + if ((svga->displine + svga->y_add) < 0) + return; + + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 8; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; + + svga->ma += 4; + p += 4; + } + } + svga->ma &= svga->vram_display_mask; + } + } +} + // TODO: Integrate more of this into the generic paletted renderer --GM #if 0 void From 7d9b10d5568b0f4202f3731bbf94f7efa7c2d76f Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 16 Dec 2023 14:35:52 -0500 Subject: [PATCH 004/146] Correct undevbranching of the Matrox Millenium --- src/include/86box/video.h | 2 +- src/video/CMakeLists.txt | 4 ++++ src/video/vid_table.c | 2 +- src/win/Makefile.mingw | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 0d435fd369c..396b391241d 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -433,7 +433,7 @@ extern const device_t pgc_device; /* Matrox MGA */ extern const device_t millennium_device; -# if defined(DEV_BRANCH) +# if defined(DEV_BRANCH) && defined(USE_MGA) extern const device_t mystique_device; extern const device_t mystique_220_device; # endif diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 638837757ae..6635252a6d6 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,6 +28,10 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) +if(MGA) + target_compile_definitions(vid PRIVATE USE_MGA) +endif() + if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 04d48c9d989..6317fb5a326 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -205,7 +205,7 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, -#if defined(DEV_BRANCH) +#if defined(DEV_BRANCH) && defined(USE_MGA) { &mystique_device }, { &mystique_220_device }, #endif diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 022a639f25f..13dbdcefedb 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -498,7 +498,6 @@ ifeq ($(DEV_BRANCH), y) ifeq ($(MGA), y) OPTS += -DUSE_MGA - DEVBROBJ += vid_mga.o endif ifeq ($(OPEN_AT), y) @@ -765,6 +764,7 @@ VIDOBJ := agpgart.o video.o \ vid_s3.o vid_s3_virge.o \ vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \ vid_ogc.o \ + vid_mga.o \ vid_nga.o \ vid_tvp3026_ramdac.o \ vid_xga.o From d3fbd93848ed717c5116284534740a166aae243c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 16 Dec 2023 20:36:34 +0100 Subject: [PATCH 005/146] Fixed warning in vid_mga.c. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 86b3c3a921f..30d6b453ad1 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3944,7 +3944,7 @@ static void blit_line(mystique_t *mystique, int closed) { svga_t *svga = &mystique->svga; - uint32_t src; + uint32_t src = 0; uint32_t dst; uint32_t old_dst; int x; From 48513fe6aa85d27f6a21770997328806a246bcf0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:45:03 +0100 Subject: [PATCH 006/146] Fixed two warnings in codegen_new/codegen_backend_x86-64.c. --- src/codegen_new/codegen_backend_x86-64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index 67355539b12..3cbca28f88f 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -73,7 +73,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ESI = address Out - ECX = data, ESI = abrt*/ @@ -161,7 +161,7 @@ static void build_store_routine(codeblock_t *block, int size, int is_float) { uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *misaligned_offset = NULL; /*In - ECX = data, ESI = address Out - ESI = abrt From 0848f4a38e049e512db2eaee16ff184850cda3c2 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Sun, 17 Dec 2023 08:46:12 +1300 Subject: [PATCH 007/146] Disable blink in 8bpp modes on MGA; Re-instate main 8bpp hires renderer I don't actually know if 8bpp blink is a thing on a Matrox Millennium, but the video BIOS seems to act like it's not. --- src/include/86box/vid_svga.h | 5 +++++ src/video/vid_mga.c | 4 +++- src/video/vid_svga_render.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index f725996d891..cb914aca9c0 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -246,6 +246,11 @@ typedef struct svga_t { addresses are shifted to match*/ int packed_chain4; + /*Disable 8bpp blink mode - some cards support it, some don't, it's a weird mode + If mode 13h appears in a reddish-brown background (0x88) with dark green text (0x8F), + you should set this flag when entering that mode*/ + int disable_blink; + /*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/ int force_dword_mode; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 30d6b453ad1..320cd899af6 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -935,7 +935,7 @@ mystique_recalctimings(svga_t *svga) } else { switch (svga->bpp) { case 8: - svga->render = svga_render_8bpp_incompatible_highres; + svga->render = svga_render_8bpp_highres; break; case 15: svga->render = svga_render_15bpp_highres; @@ -958,6 +958,8 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) svga->bpp = 8; } + + svga->disable_blink = (svga->bpp > 4); } static void diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index f7bc36130d9..7a15dc1cfe6 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -457,7 +457,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t changed_offset; const bool blinked = svga->blink & 0x10; - const bool attrblink = ((svga->attrregs[0x10] & 0x08) != 0); + const bool attrblink = (!svga->disable_blink) && ((svga->attrregs[0x10] & 0x08) != 0); /* The following is likely how it works on an IBM VGA - that is, it works with its BIOS. From e7f15d87e1b7838c5e2e29818cf40664a0133e7b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:47:11 +0100 Subject: [PATCH 008/146] And the warning in disk/zip.c. --- src/disk/zip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disk/zip.c b/src/disk/zip.c index 7045b1e41cf..d4b6448654f 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -531,7 +531,7 @@ zip_load(zip_t *dev, char *fn) if (fseek(dev->drv->fp, dev->drv->base, SEEK_SET) == -1) fatal("zip_load(): Error seeking to the beginning of the file\n"); - strncpy(dev->drv->image_path, fn, sizeof(dev->drv->image_path) - 1); + strncpy(dev->drv->image_path, fn, strlen(dev->drv->image_path) + 1); return 1; } From c2a89f64b2298b9a2a533f84a2aabb0a676339d1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:56:45 +0100 Subject: [PATCH 009/146] Fixed the warnings in sio/sio_it86x1f.c. --- src/sio/sio_it86x1f.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sio/sio_it86x1f.c b/src/sio/sio_it86x1f.c index d53e7805050..74e79bbedb2 100644 --- a/src/sio/sio_it86x1f.c +++ b/src/sio/sio_it86x1f.c @@ -14,9 +14,10 @@ * * Copyright 2023 RichardG. */ +#include #include -#include #include +#include #include #include #include @@ -805,10 +806,18 @@ it86x1f_init(UNUSED(const device_t *info)) break; } if (i >= (sizeof(it86x1f_models) / sizeof(it86x1f_models[0]))) { +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + fatal("IT86x1F: Unknown type %04" PRIX64 " selected\n", info->local); +#else fatal("IT86x1F: Unknown type %04X selected\n", info->local); +#endif return NULL; } +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + it86x1f_log("IT86x1F: init(%04" PRIX64 ")\n", info->local); +#else it86x1f_log("IT86x1F: init(%04X)\n", info->local); +#endif /* Let the resource data parser figure out the ROM size. */ dev->pnp_card = isapnp_add_card(it86x1f_models[i].pnp_rom, -1, it86x1f_models[i].pnp_config_changed, NULL, it86x1f_pnp_read_vendor_reg, it86x1f_pnp_write_vendor_reg, dev); From a76e3890b289f56200ee8c40f5eb5a08473113d6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 16 Dec 2023 20:57:58 +0100 Subject: [PATCH 010/146] And the one in sio/sio_um8669f.c. --- src/sio/sio_um8669f.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sio/sio_um8669f.c b/src/sio/sio_um8669f.c index 61e9abd97b1..136b1add6e8 100644 --- a/src/sio/sio_um8669f.c +++ b/src/sio/sio_um8669f.c @@ -222,7 +222,11 @@ um8669f_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *pri if (dev->ide < IDE_BUS_MAX) { config->io[1].base = config->io[0].base + 0x206; /* status port apparently fixed */ +#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + ide_pnp_config_changed(0, config, (void *) (int64_t) dev->ide); +#else ide_pnp_config_changed(0, config, (void *) (int) dev->ide); +#endif } break; From 4b402c22cdb6634bbb5bb479253bc07ff216fbbd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 16 Dec 2023 18:26:39 -0300 Subject: [PATCH 011/146] vid_mga: Implement DDC on the Millennium --- src/include/86box/vid_svga.h | 1 + src/video/vid_mga.c | 22 ++++++++++++++++++++ src/video/vid_tvp3026_ramdac.c | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index cb914aca9c0..682a66111b1 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -398,6 +398,7 @@ extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, sv extern void tvp3026_recalctimings(void *priv, svga_t *svga); extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); extern float tvp3026_getclock(int clock, void *priv); +extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); # ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 320cd899af6..2f701b33f2f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5314,6 +5314,27 @@ mystique_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +static uint8_t +mystique_tvp3026_gpio_read(uint8_t cntl, void *priv) +{ + mystique_t *mystique = (mystique_t *) priv; + + uint8_t ret = 0xff; + if (!i2c_gpio_get_scl(mystique->i2c_ddc)) + ret &= ~0x10; + if (!i2c_gpio_get_sda(mystique->i2c_ddc)) + ret &= ~0x04; + return ret; +} + +static void +mystique_tvp3026_gpio_write(uint8_t cntl, uint8_t data, void *priv) +{ + mystique_t *mystique = (mystique_t *) priv; + + i2c_gpio_set(mystique->i2c_ddc, !(cntl & 0x10) || (data & 0x10), !(cntl & 0x04) || (data & 0x04)); +} + static uint8_t mystique_pci_read(UNUSED(int func), int addr, void *priv) { @@ -5625,6 +5646,7 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 15215c45d09..611527a358d 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -55,6 +55,11 @@ typedef struct tvp3026_ramdac_t { uint8_t n; uint8_t p; } pix, mem, loop; + uint8_t gpio_cntl; + uint8_t gpio_data; + uint8_t (*gpio_read)(uint8_t cntl, void *priv); + void (*gpio_write)(uint8_t cntl, uint8_t val, void *priv); + void *gpio_priv; } tvp3026_ramdac_t; static void @@ -211,6 +216,16 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg ramdac->misc = val; svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; break; + case 0x2a: /* General-Purpose I/O Control */ + ramdac->gpio_cntl = val; + if (ramdac->gpio_write) + ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv); + break; + case 0x2b: /* General-Purpose I/O Data */ + ramdac->gpio_data = val; + if (ramdac->gpio_write) + ramdac->gpio_write(ramdac->gpio_cntl, ramdac->gpio_data, ramdac->gpio_priv); + break; case 0x2c: /* PLL Address */ ramdac->pll_addr = val; break; @@ -389,6 +404,16 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) case 0x1e: /* Miscellaneous Control */ temp = ramdac->misc; break; + case 0x2a: /* General-Purpose I/O Control */ + temp = ramdac->gpio_cntl; + break; + case 0x2b: /* General-Purpose I/O Data */ + if (ramdac->gpio_read) { + temp = 0xe0 | (ramdac->gpio_cntl & 0x1f); /* keep upper bits untouched */ + ramdac->gpio_data = (ramdac->gpio_data & temp) | (ramdac->gpio_read(ramdac->gpio_cntl, ramdac->gpio_priv) & ~temp); + } + temp = ramdac->gpio_data; + break; case 0x2c: /* PLL Address */ temp = ramdac->pll_addr; break; @@ -630,6 +655,18 @@ tvp3026_getclock(int clock, void *priv) return f_pll; } +void +tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), + void (*write)(uint8_t cntl, uint8_t val, void *priv), + void *cb_priv, void *priv) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; + + ramdac->gpio_read = read; + ramdac->gpio_write = write; + ramdac->gpio_priv = cb_priv; +} + void * tvp3026_ramdac_init(const device_t *info) { From aa0b4dfab7c34569aea26f8ab98520b16c9d4885 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 17 Dec 2023 12:43:07 +0100 Subject: [PATCH 012/146] ALi M1543(c) ACPI and SMBUS PCI BAR's now correctly return all 0x00's when locked, as documented by the M1543 datasheet, fixes the PCI error found by Dizzy on the ASUS P5A with Debian Lenny. --- src/chipset/ali1543.c | 107 +++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 4d8dea3ce21..fb9fd70ceed 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -984,7 +984,7 @@ static void ali7101_write(int func, int addr, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; - ali1543_log("M7101: dev->pmu_conf[%02x] = %02x\n", addr, val); + ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val); if (func > 0) return; @@ -1408,65 +1408,78 @@ ali7101_read(int func, int addr, void *priv) uint8_t ret = 0xff; if (dev->pmu_dev_enable && (func == 0)) { - if ((dev->pmu_conf[0xc9] & 0x01) && (addr >= 0x40) && (addr != 0xc9)) - return 0xff; - - /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ - switch (addr) { - default: - ret = dev->pmu_conf[addr]; - break; - case 0x42: - ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); - break; - case 0x43: - ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; - break; - case 0x7f: - ret = 0x80; - break; - case 0xbc: - ret = inb(0x70); - break; - } - - if (dev->pmu_conf[0x77] & 0x10) { + if (!(dev->pmu_conf[0xc9] & 0x01) || (addr < 0x40) || (addr == 0xc9)) { + /* TODO: C4, C5 = GPIREG (masks: 0D, 0E) */ switch (addr) { - case 0x42: - dev->pmu_conf[addr] &= 0xe0; - break; - case 0x43: - dev->pmu_conf[addr] &= 0xef; - acpi_ali_soft_smi_status_write(dev->acpi, 0); + default: + ret = dev->pmu_conf[addr]; break; - - case 0x48: - dev->pmu_conf[addr] = 0x00; + case 0x10 ... 0x13: + if (dev->pmu_conf[0x5b] & 0x02) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; break; - case 0x49: - dev->pmu_conf[addr] &= 0x60; + case 0x14 ... 0x17: + if (dev->pmu_conf[0x5b] & 0x04) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; break; - case 0x4a: - dev->pmu_conf[addr] &= 0xc7; + case 0x42: + ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); break; - - case 0x4e: - dev->pmu_conf[addr] &= 0xfa; + case 0x43: + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; break; - case 0x4f: - dev->pmu_conf[addr] &= 0xfe; + case 0x7f: + ret = 0x80; break; - - case 0x74: - dev->pmu_conf[addr] &= 0xcc; + case 0xbc: + ret = inb(0x70); break; + } - default: - break; + if (dev->pmu_conf[0x77] & 0x10) { + switch (addr) { + case 0x42: + dev->pmu_conf[addr] &= 0xe0; + break; + case 0x43: + dev->pmu_conf[addr] &= 0xef; + acpi_ali_soft_smi_status_write(dev->acpi, 0); + break; + + case 0x48: + dev->pmu_conf[addr] = 0x00; + break; + case 0x49: + dev->pmu_conf[addr] &= 0x60; + break; + case 0x4a: + dev->pmu_conf[addr] &= 0xc7; + break; + + case 0x4e: + dev->pmu_conf[addr] &= 0xfa; + break; + case 0x4f: + dev->pmu_conf[addr] &= 0xfe; + break; + + case 0x74: + dev->pmu_conf[addr] &= 0xcc; + break; + + default: + break; + } } } } + ali1543_log("M7101: [R] dev->pmu_conf[%02x] = %02x\n", addr, ret); + return ret; } From 4c87164692f39af790c1a864eea82fb2d487c691 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 17 Dec 2023 12:49:10 -0500 Subject: [PATCH 013/146] Fix remaining warnings in windows and linux builds --- src/config.c | 32 ++++++++++++++++---------------- src/include/86box/86box.h | 2 +- src/network/net_rtl8139.c | 2 +- src/unix/unix.c | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/config.c b/src/config.c index b1ed7094faf..8c4ad0de400 100644 --- a/src/config.c +++ b/src/config.c @@ -1104,13 +1104,13 @@ load_floppy_and_cdrom_drives(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 255) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 255 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " "(fdd_image_history[%i][%i])\n", c, i); else - snprintf(fdd_image_history[c][i], 255, "%s", p); + snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(fdd_image_history[c][i], 255, "%s%s%s", usr_path, + snprintf(fdd_image_history[c][i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(fdd_image_history[c][i]); } @@ -1220,13 +1220,13 @@ load_floppy_and_cdrom_drives(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_floppy_and_cdrom_drives(): strlen(p) > 511 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_floppy_and_cdrom_drives(): strlen(p) > 2047 " "(cdrom[%i].image_history[%i])\n", c, i); else - snprintf(cdrom[c].image_history[i], 511, "%s", p); + snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(cdrom[c].image_history[i], 511, "%s%s%s", usr_path, + snprintf(cdrom[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(cdrom[c].image_history[i]); } @@ -1353,13 +1353,13 @@ load_other_removable_devices(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_other_removable_devices(): strlen(p) > 511 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_other_removable_devices(): strlen(p) > 2047 " "(zip_drives[%i].image_history[%i])\n", c, i); else - snprintf(zip_drives[c].image_history[i], 511, "%s", p); + snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(zip_drives[c].image_history[i], 511, "%s%s%s", usr_path, + snprintf(zip_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(zip_drives[c].image_history[i]); } @@ -1469,13 +1469,13 @@ load_other_removable_devices(void) p = ini_section_get_string(cat, temp, NULL); if (p) { if (path_abs(p)) { - if (strlen(p) > 511) - fatal("load_other_removable_devices(): strlen(p) > 511 " + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("load_other_removable_devices(): strlen(p) > 2047 " "(mo_drives[%i].image_history[%i])\n", c, i); else - snprintf(mo_drives[c].image_history[i], 511, "%s", p); + snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s", p); } else - snprintf(mo_drives[c].image_history[i], 511, "%s%s%s", usr_path, + snprintf(mo_drives[c].image_history[i], (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, path_get_slash(usr_path), p); path_normalize(mo_drives[c].image_history[i]); } diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index ae2ea260caf..c16cd5efb55 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -33,7 +33,7 @@ /* Recently used images */ #define MAX_PREV_IMAGES 4 -#define MAX_IMAGE_PATH_LEN 256 +#define MAX_IMAGE_PATH_LEN 2048 /* Default language 0xFFFF = from system, 0x409 = en-US */ #define DEFAULT_LANGUAGE 0x0409 diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index d1e14fb122d..6c86bdebfbe 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3312,7 +3312,7 @@ nic_init(const device_t *info) fp = nvr_fopen(eeprom_filename, "rb"); if (fp) { - fread(s->eeprom.contents, 2, 64, fp); + (void) !fread(s->eeprom.contents, 2, 64, fp); fclose(fp); fp = NULL; } else { diff --git a/src/unix/unix.c b/src/unix/unix.c index ecd17cadb90..bac84ead49c 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -918,7 +918,7 @@ monitor_thread(void *param) line = f_readline("(86Box) "); else { printf("(86Box) "); - !getline(&line, &n, stdin); + (void) !getline(&line, &n, stdin); } if (line) { int cmdargc = 0; From c62182cd2e43f461952a74c60ead03022dae65db Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 00:08:51 +0100 Subject: [PATCH 014/146] MGA Fixes: 1. LFB access is now done properly through the right svga_read/write linear calls. 2. Lowres 8bpp mode and Packed/Extended 8bpp+ mode don't mix together, fixes Debian Woody matroxfb module when testing the modes while keeping other compatibility intact (basically enable packed stuff only when gdcreg5 bits 5-6 are 0 when extended mode is set). 3. Small cleanup in the line accel stuff. --- src/video/vid_mga.c | 95 ++++++++++++++------------------------------- 1 file changed, 29 insertions(+), 66 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2f701b33f2f..cadf64bb81d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -720,15 +720,10 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); + if (mystique->crtcext_idx != 3) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { @@ -880,7 +875,6 @@ mystique_recalctimings(svga_t *svga) svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; svga->hdisp = (svga->crtc[1] + 1) * 8; @@ -891,6 +885,7 @@ mystique_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->ma_latch <<= 1; } + if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ @@ -903,7 +898,6 @@ mystique_recalctimings(svga_t *svga) } svga->rowoffset <<= 1; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: case XMULCTRL_DEPTH_2G8V16: @@ -952,6 +946,7 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; + svga->packed_chain4 = ((svga->gdcreg[5] & 0x60) == 0x00); } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -959,7 +954,11 @@ mystique_recalctimings(svga_t *svga) svga->bpp = 8; } + svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); +#if 0 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); +#endif } static void @@ -2563,6 +2562,7 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { @@ -2616,7 +2616,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; svga->vram[addr] = val; } @@ -2631,7 +2631,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint16_t *) &svga->vram[addr] = val; } @@ -2646,9 +2646,10 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } +#endif static void run_dma(mystique_t *mystique) @@ -3950,102 +3951,67 @@ blit_line(mystique_t *mystique, int closed) uint32_t dst; uint32_t old_dst; int x; + int len = 0; int z_write; - int pattern; - int funcnt = mystique->dwgreg.funcnt; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_RSTR: case DWGCTRL_ATYPE_RPL: x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length >= 0) { - pattern = mystique->dwgreg.src[0] & (1 << funcnt); - + while (len <= mystique->dwgreg.length) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); if (closed) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; } break; case MACCESS_PWIDTH_16: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); if (closed) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; } break; case MACCESS_PWIDTH_24: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); if (closed) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; } break; case MACCESS_PWIDTH_32: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_SOLID) - src = mystique->dwgreg.fcol; - else { - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (pattern) - src = mystique->dwgreg.fcol; - } else - src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - } + src = mystique->dwgreg.fcol; dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); if (closed) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - } else if (!closed && mystique->dwgreg.length > 0) { + } else if (!closed && (len < mystique->dwgreg.length)) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; } @@ -4070,10 +4036,7 @@ blit_line(mystique_t *mystique, int closed) } else mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; - funcnt = (funcnt - 1) & mystique->dwgreg.stylelen; - if (mystique->dwgreg.length == 0xffff) - break; + len++; } break; @@ -5666,9 +5629,9 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, - mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, From 8e74ee27267d877a1229db48ee392f6fb1299fb1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 17 Dec 2023 15:34:18 -0500 Subject: [PATCH 015/146] Fix most of the warnings in the macos builds --- src/chipset/ali1543.c | 2 -- src/qt/qt_renderercommon.cpp | 2 +- src/unix/unix.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index fb9fd70ceed..fe3a0fda31e 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -489,12 +489,10 @@ static void ali5229_ide_irq_handler(ali1543_t *dev) { int ctl = 0; - int ch = 0; int bit = 0; if (dev->ide_conf[0x52] & 0x10) { ctl ^= 1; - ch ^= 1; bit ^= 5; } diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 983f14d2640..05c35e09bb3 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -88,7 +88,7 @@ RendererCommon::onResize(int width, int height) if (video_fullscreen_scale == FULLSCR_SCALE_INT43) { gh = gw / r43; - gw = gw; +// gw = gw; gsr = r43; } diff --git a/src/unix/unix.c b/src/unix/unix.c index bac84ead49c..cf69997b09f 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -830,7 +830,7 @@ plat_init_rom_paths(void) rom_add_path("/usr/share/86Box/roms/"); } #else - char default_rom_path[1024] = { '\0 ' }; + char default_rom_path[1024] = { '\0' }; getDefaultROMPath(default_rom_path); rom_add_path(default_rom_path); #endif From c1ba150e3c5335a5bc3b2ba86ed96c980daff34f Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 00:40:31 +0100 Subject: [PATCH 016/146] Oops, they actually can mix together, but not with plain (non-packed) chain4 stuff enabled, should fix more mode issues in the MGA Millennium card. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index cadf64bb81d..69d8de0f84b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -946,7 +946,7 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; - svga->packed_chain4 = ((svga->gdcreg[5] & 0x60) == 0x00); + svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; From 9573d373643ae7e0532f41a974c5f62544f55fd3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 00:41:51 +0100 Subject: [PATCH 017/146] And warning fixes. --- src/video/vid_mga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 69d8de0f84b..c505b5cc2c0 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -634,12 +634,14 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); +#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); From 80e5c4f5ac0931bf5f5e7878921103488ab44343 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 18 Dec 2023 10:02:18 +0100 Subject: [PATCH 018/146] Temporarily reverted all the Matrox mode changes since they broke even standard SVGA modes. --- src/video/vid_mga.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c505b5cc2c0..7b1db7cc897 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -634,14 +634,12 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); -#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); @@ -722,10 +720,15 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); if (mystique->crtcext_idx < 4) { - if (mystique->crtcext_idx != 3) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 3) { + if (val & CRTCX_R3_MGAMODE) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(svga); } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { @@ -877,6 +880,7 @@ mystique_recalctimings(svga_t *svga) svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; svga->hdisp = (svga->crtc[1] + 1) * 8; @@ -887,7 +891,6 @@ mystique_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->ma_latch <<= 1; } - if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ @@ -900,6 +903,7 @@ mystique_recalctimings(svga_t *svga) } svga->rowoffset <<= 1; + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: case XMULCTRL_DEPTH_2G8V16: @@ -948,7 +952,6 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; - svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -956,11 +959,7 @@ mystique_recalctimings(svga_t *svga) svga->bpp = 8; } - svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); -#if 0 - pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); -#endif } static void @@ -2564,7 +2563,6 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { @@ -2618,7 +2616,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->changedvram[addr >> 12] = changeframecount; svga->vram[addr] = val; } @@ -2633,7 +2631,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->changedvram[addr >> 12] = changeframecount; *(uint16_t *) &svga->vram[addr] = val; } @@ -2648,10 +2646,9 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; + svga->changedvram[addr >> 12] = changeframecount; *(uint32_t *) &svga->vram[addr] = val; } -#endif static void run_dma(mystique_t *mystique) @@ -5631,9 +5628,9 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear, - NULL, 0, &mystique->svga); + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, + NULL, 0, mystique); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, @@ -5804,6 +5801,7 @@ const device_t millennium_device = { .config = mystique_config }; +#if defined(DEV_BRANCH) && defined(USE_MGA) const device_t mystique_device = { .name = "Matrox Mystique", .internal_name = "mystique", @@ -5831,3 +5829,4 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; +#endif From f5642ab1c3f10e40004f0945c3cffa37e413455c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 13:42:32 +0100 Subject: [PATCH 019/146] MGA fixes 2: 1. Reverted the packed chain4 and fb_only sides to 1 when extended mode is set, but with the call to svga_recalctimings removed from port 0x3df due to mode issues, this should fix all the MGA mode issues I know. 2. Cleaned up the rendering order in svga_recalctimings, especially 4bpp and 8bpp. --- src/video/vid_mga.c | 12 +++--------- src/video/vid_svga.c | 32 +++++++++----------------------- 2 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c505b5cc2c0..9289c83ce7e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -721,12 +721,6 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) mystique->crtcext_regs[mystique->crtcext_idx] = val; if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); - if (mystique->crtcext_idx < 4) { - if (mystique->crtcext_idx != 3) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -947,8 +941,8 @@ mystique_recalctimings(svga_t *svga) break; } } + svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; - svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -958,8 +952,8 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); -#if 0 - pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); +#if 1 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); #endif } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 5f5efcd9e4f..1479ea7181f 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -639,27 +639,21 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if (svga->bpp <= 8) { - if (svga->attrregs[0x10] & 0x40) { /*8bpp mode*/ - svga->map8 = svga->pallook; - if (svga->lowres) /*Low res (320)*/ - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - } else { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; + } else { + svga->map8 = svga->pallook; + if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; case 0x20: /*4 colours*/ if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_2bpp_lowres; @@ -669,13 +663,6 @@ svga_recalctimings(svga_t *svga) case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; case 15: if (svga->lowres) svga->render = svga_render_15bpp_lowres; @@ -1920,9 +1907,8 @@ svga_readl_common(uint32_t addr, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - if (!svga->fast) { + if (!svga->fast) return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8) | (svga_read_common(addr + 2, linear, priv) << 16) | (svga_read_common(addr + 3, linear, priv) << 24); - } cycles -= svga->monitor->mon_video_timing_read_l; From 718fb759af92681644f354f68dccf9c5fe88e695 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 13:47:23 +0100 Subject: [PATCH 020/146] There, log excess disabled. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 9289c83ce7e..b2212d268f3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -952,7 +952,7 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); -#if 1 +#if 0 pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); #endif } From c7f4e59e49d4233d7cf5c938540efb70db9b4810 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 18 Dec 2023 13:57:33 +0100 Subject: [PATCH 021/146] Restoring the old changes. --- src/video/vid_mga.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7b1db7cc897..a1486cb27ee 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -634,12 +634,14 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); +#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); @@ -720,15 +722,10 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); + if (mystique->crtcext_idx != 3) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { @@ -880,7 +877,6 @@ mystique_recalctimings(svga_t *svga) svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; svga->lowres = 0; svga->char_width = 8; svga->hdisp = (svga->crtc[1] + 1) * 8; @@ -891,6 +887,7 @@ mystique_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->ma_latch <<= 1; } + if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ @@ -903,7 +900,6 @@ mystique_recalctimings(svga_t *svga) } svga->rowoffset <<= 1; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: case XMULCTRL_DEPTH_2G8V16: @@ -952,6 +948,7 @@ mystique_recalctimings(svga_t *svga) } } svga->line_compare = mystique_line_compare; + svga->packed_chain4 = !svga->chain4; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; @@ -959,7 +956,11 @@ mystique_recalctimings(svga_t *svga) svga->bpp = 8; } + svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); +#if 0 + pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60); +#endif } static void @@ -2563,6 +2564,7 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } +#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { @@ -2616,7 +2618,7 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; svga->vram[addr] = val; } @@ -2631,7 +2633,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint16_t *) &svga->vram[addr] = val; } @@ -2646,9 +2648,10 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) if (addr >= svga->vram_max) return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } +#endif static void run_dma(mystique_t *mystique) @@ -5628,9 +5631,9 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, - mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, From 552740b2bd64d0bae1ce929017a2bedf5f6fc4b2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 14:01:38 +0100 Subject: [PATCH 022/146] S3 wraparound fix. Just a quick fix for Commander Keen 4 EGA's flickering. --- src/video/vid_s3.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index f35f729dac9..35e65cc182d 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2576,17 +2576,11 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x3C7: case 0x3C8: case 0x3C9: - if ((svga->crtc[0x55] & 0x03) == 0x00) - rs2 = !!(svga->crtc[0x43] & 0x02); - else - rs2 = (svga->crtc[0x55] & 0x01); + rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) svga_out(addr, val, svga); else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (!(svga->crtc[0x45] & 0x20) || (s3->chip == S3_86C928)) - rs3 = !!(svga->crtc[0x55] & 0x02); - else - rs3 = 0; + rs3 = !!(svga->crtc[0x55] & 0x02); bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); @@ -2633,10 +2627,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->force_dword_mode = !!(val & 0x08); break; case 0x32: - if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) - svga->vram_display_mask = 0x3ffff; - else - svga->vram_display_mask = s3->vram_mask; + svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; break; case 0x40: From 313bf84b04d8a53731aa8e4ac3b13f96d214e0a1 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Mon, 18 Dec 2023 15:42:24 -0300 Subject: [PATCH 023/146] i2c_eeprom: Random cleanups --- src/mem/i2c_eeprom.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/mem/i2c_eeprom.c b/src/mem/i2c_eeprom.c index 7d83bbe88a1..8e4a6cc1414 100644 --- a/src/mem/i2c_eeprom.c +++ b/src/mem/i2c_eeprom.c @@ -60,7 +60,7 @@ i2c_eeprom_start(UNUSED(void *bus), uint8_t addr, uint8_t read, void *priv) { i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; - i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr); + i2c_eeprom_log("I2C EEPROM %s %02X: start(%c)\n", i2c_getbusname(dev->i2c), dev->addr, read ? 'R' : 'W'); if (!read) { dev->addr_pos = 0; @@ -77,8 +77,7 @@ i2c_eeprom_read(UNUSED(void *bus), UNUSED(uint8_t addr), void *priv) uint8_t ret = dev->data[dev->addr_register]; i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret); - dev->addr_register++; - dev->addr_register &= dev->addr_mask; /* roll-over */ + dev->addr_register = (dev->addr_register + 1) & dev->addr_mask; /* roll-over */ return ret; } @@ -100,8 +99,7 @@ i2c_eeprom_write(UNUSED(void *bus), uint8_t addr, uint8_t data, void *priv) i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable); if (dev->writable) dev->data[dev->addr_register] = data; - dev->addr_register++; - dev->addr_register &= dev->addr_mask; /* roll-over */ + dev->addr_register = (dev->addr_register + 1) & dev->addr_mask; /* roll-over */ return dev->writable; } @@ -137,7 +135,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w uint32_t pow_size = 1 << log2i(size); if (pow_size < size) size = pow_size << 1; - size &= 0x7fffff; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits */ + if (size >= 8388608) + size = 8388608; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits from command address */ i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable); @@ -149,7 +148,8 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */ dev->addr_mask = size - 1; - i2c_sethandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); + uint8_t i2c_mask = dev->addr_mask >> dev->addr_len; + i2c_sethandler(dev->i2c, dev->addr & ~i2c_mask, i2c_mask + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); return dev; } @@ -161,7 +161,8 @@ i2c_eeprom_close(void *dev_handle) i2c_eeprom_log("I2C EEPROM %s %02X: close()\n", i2c_getbusname(dev->i2c), dev->addr); - i2c_removehandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); + uint8_t i2c_mask = dev->addr_mask >> dev->addr_len; + i2c_removehandler(dev->i2c, dev->addr & ~i2c_mask, i2c_mask + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev); free(dev); } From 12d5d6c26085d8380b35a7b14c06dfea85845d48 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 02:18:08 +0600 Subject: [PATCH 024/146] Matrox Mystique: Bus-mastering fixes * Make all bus-mastering-related variables atomic * Do not, under any circumstances, attempt to read beyond PRIMEND and SECEND This allows NT 4.0's Mystique drivers to work with busmastering enabled. --- src/video/vid_mga.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d066adb738b..0cf35bdd9be 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -55,7 +55,7 @@ #define FIFO_ADDR 0x00ffffff #define DMA_POLL_TIME_US 100 /*100us*/ -#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ +#define DMA_MAX_WORDS (20 * 14) /*280 quad words per 100us poll*/ /*These registers are also mirrored into 0x1dxx, with the mirrored versions starting the blitter*/ @@ -505,10 +505,10 @@ typedef struct mystique_t { struct { - int pri_pos, sec_pos, iload_pos, + atomic_int pri_pos, sec_pos, iload_pos, pri_state, sec_state, iload_state, state; - uint32_t primaddress, primend, secaddress, secend, + atomic_uint primaddress, primend, secaddress, secend, pri_header, sec_header, iload_header; @@ -2660,21 +2660,23 @@ run_dma(mystique_t *mystique) } while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { - switch (mystique->dma.state) { + switch (atomic_load(&mystique->dma.state)) { case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if (mystique->dma.pri_state == 0) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; + words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15) { + if ((mystique->dma.pri_header & 0xff) != 0x15 || (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.primaddress += 4; + words_transferred++; reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2691,10 +2693,9 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - words_transferred++; if (mystique->dma.state == DMA_STATE_SEC) mystique->dma.pri_state = 0; - else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } @@ -2711,6 +2712,7 @@ run_dma(mystique_t *mystique) if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; + words_transferred++; } uint32_t val; @@ -2734,8 +2736,8 @@ run_dma(mystique_t *mystique) mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } else @@ -2754,8 +2756,8 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } else From 111b6238110466a9b35ae9ff6c0670b06eb1da78 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 03:00:54 +0600 Subject: [PATCH 025/146] Fix logical error --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0cf35bdd9be..2c9561b020b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2670,7 +2670,7 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15 || (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { uint32_t val; uint32_t reg_addr; From 46c5f9c0ccb053656dee94bf28b95f5b2e0ec8ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 18 Dec 2023 22:33:15 +0100 Subject: [PATCH 026/146] Added a missing sanity check to device/isapnp.c, fixes crash with ISA PnP sound cards on the PB520R. --- src/device/isapnp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/isapnp.c b/src/device/isapnp.c index 7b9d570bb41..f9d10b3801e 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -124,7 +124,7 @@ static void isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) { /* Ignore card if it hasn't signed up for configuration changes. */ - if (!card->config_changed) + if ((card == NULL) || !card->config_changed) return; /* Populate config structure, performing endianness conversion as needed. */ From ff446fab9b6c2144417d73d058a08ed20fa77914 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 18 Dec 2023 09:20:37 +0500 Subject: [PATCH 027/146] prt_escp.c: Fall back to roman.ttf instead of dotmatrix.ttf for unhandled typefaces --- src/printer/prt_escp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 707590134ab..cd02790784b 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -531,7 +531,7 @@ update_font(escp_t *dev) fn = FONT_FILE_OCRB; break; default: - fn = FONT_FILE_DOTMATRIX; + fn = FONT_FILE_ROMAN; } /* Create a full pathname for the ROM file. */ From bf1f4252672eb2607cd00da65b45c03a377c3193 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 18 Dec 2023 09:20:48 +0500 Subject: [PATCH 028/146] prt_escp.c: Try to use courier.ttf if dotmatrix.ttf is missing --- src/printer/prt_escp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index cd02790784b..c1147978681 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -545,6 +545,17 @@ update_font(escp_t *dev) if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; + + /* Try to fall back to Courier in case the dot matrix font is absent. */ + if (!strcmp(fn, FONT_FILE_DOTMATRIX)) { + strcpy(path, dev->fontpath); + path_slash(path); + strcat(path, FONT_FILE_COURIER); + if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { + escp_log("ESC/P: unable to load font '%s'\n", path); + dev->fontface = NULL; + } + } } if (!dev->multipoint_mode) { From 6eb05e14d5f0842e66838580a69337ed43970e3c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 18 Dec 2023 23:43:37 +0100 Subject: [PATCH 029/146] ATI EGA Wonder 800+ and 18800 refactoring: 1. Proper cleanup of the code. 2. Migrate the card in question to the VGA class list as it's actually a rebadged VGA Edge (thus 18800). 3. Some VGA only features are not supported on this card and are documented in the recalctimings. --- src/include/86box/vid_ega.h | 3 - src/include/86box/video.h | 1 + src/video/vid_ati18800.c | 176 ++++++++++++++++++++++++++++-------- src/video/vid_ega.c | 105 +-------------------- src/video/vid_table.c | 2 +- 5 files changed, 142 insertions(+), 145 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index 180803c8af7..ec13de928cc 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -132,8 +132,6 @@ typedef struct ega_t { double dot_clock; - void * eeprom; - uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); void (*render)(struct ega_t *svga); } ega_t; @@ -143,7 +141,6 @@ typedef struct ega_t { extern const device_t ega_device; extern const device_t cpqega_device; extern const device_t sega_device; -extern const device_t atiega_device; extern const device_t iskra_ega_device; extern const device_t et2000_device; #endif diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 396b391241d..de27fcbb1fa 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -322,6 +322,7 @@ extern const device_t ati18800_wonder_device; # endif extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; +extern const device_t ati18800_egawonder800plus_device; /* ATi 28800 */ extern const device_t ati28800_device; diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 5847faa39fb..fd658eacfbf 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -35,17 +35,20 @@ #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) # define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" #endif -#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" -#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" +#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" +#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" +#define BIOS_ROM_PATH_ATIEGAPLUS "roms/video/ati18800/ATI EGA Wonder 800+ N1.00.BIN" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, - ATI18800_EDGE16 + ATI18800_EDGE16, + ATI18800_EGAWONDER800PLUS #else ATI18800_VGA88 = 0, - ATI18800_EDGE16 + ATI18800_EDGE16, + ATI18800_EGAWONDER800PLUS #endif }; @@ -57,6 +60,8 @@ typedef struct ati18800_t { uint8_t regs[256]; int index; + int type; + uint32_t memory; } ati18800_t; static video_timings_t timing_ati18800 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; @@ -76,19 +81,20 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) ati18800->index = val; break; case 0x1cf: + old = ati18800->regs[ati18800->index]; ati18800->regs[ati18800->index] = val; switch (ati18800->index) { case 0xb0: - svga_recalctimings(svga); + if ((old ^ val) & 6) + svga_recalctimings(svga); break; case 0xb2: case 0xbe: - if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + if (ati18800->regs[0xbe] & 8) { /*Read/write bank mode*/ + svga->read_bank = ((ati18800->regs[0xb2] & 0xe0) >> 5) * 0x10000; + svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000; } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] & 0x0e) >> 1) * 0x10000; break; case 0xb3: ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); @@ -172,21 +178,91 @@ static void ati18800_recalctimings(svga_t *svga) { const ati18800_t *ati18800 = (ati18800_t *) svga->priv; + int clock_sel; + + clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1); + + if (ati18800->type == ATI18800_EGAWONDER800PLUS) { + svga->crtc[5] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ + svga->crtc[0x0b] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ + + svga->hdisp_time = svga->hdisp; + + svga->hdisp = svga->crtc[1]; + svga->hdisp++; - if (svga->crtc[0x17] & 4) { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]); + + svga->hdisp_time = svga->hdisp; + svga->render = svga_render_blank; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) { /*40 column*/ + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + /* Character clock is off by 1 now in 40-line modes, on all cards. */ + svga->ma_latch--; + svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; + } else { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } else { + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; + } + } } - if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; + if (ati18800->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; svga->rowoffset <<= 1; - svga->ma <<= 1; + svga->gdcreg[5] &= ~0x40; + } + + if (ati18800->regs[0xb0] & 6) + svga->gdcreg[5] |= 0x40; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + default: + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + break; + } + break; + + default: + break; + } + } } } @@ -198,6 +274,8 @@ ati18800_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); + ati18800->type = info->local; + switch (info->local) { default: #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) @@ -207,32 +285,36 @@ ati18800_init(const device_t *info) #endif case ATI18800_VGA88: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 256; break; case ATI18800_EDGE16: rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 512; + break; + case ATI18800_EGAWONDER800PLUS: + rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_ATIEGAPLUS, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ati18800->memory = 256; break; } - if (info->local == ATI18800_EDGE16) { - svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } else { - svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } + svga_init(info, &ati18800->svga, ati18800, ati18800->memory << 10, + ati18800_recalctimings, + ati18800_in, ati18800_out, + NULL, + NULL); + ati18800->svga.clock_gen = device_add(&ati18810_device); + ati18800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); ati18800->svga.miscout = 1; + ati18800->svga.bpp = 8; - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + if (info->local == ATI18800_EGAWONDER800PLUS) + ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); + else + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); return ati18800; } @@ -257,6 +339,12 @@ ati18800_available(void) return rom_present(BIOS_ROM_PATH_EDGE16); } +static int +ati18800_egawonder800plus_available(void) +{ + return rom_present(BIOS_ROM_PATH_ATIEGAPLUS); +} + static void ati18800_close(void *priv) { @@ -300,7 +388,7 @@ const device_t ati18800_wonder_device = { #endif const device_t ati18800_vga88_device = { - .name = "ATI-18800-1", + .name = "ATI 18800-1", .internal_name = "ati18800v", .flags = DEVICE_ISA, .local = ATI18800_VGA88, @@ -314,7 +402,7 @@ const device_t ati18800_vga88_device = { }; const device_t ati18800_device = { - .name = "ATI-18800-5", + .name = "ATI VGA Edge 16", .internal_name = "ati18800", .flags = DEVICE_ISA, .local = ATI18800_EDGE16, @@ -326,3 +414,17 @@ const device_t ati18800_device = { .force_redraw = ati18800_force_redraw, .config = NULL }; + +const device_t ati18800_egawonder800plus_device = { + .name = "ATI EGA Wonder 800+", + .internal_name = "egawonder800", + .flags = DEVICE_ISA, + .local = ATI18800_EGAWONDER800PLUS, + .init = ati18800_init, + .close = ati18800_close, + .reset = NULL, + { .available = ati18800_egawonder800plus_available }, + .speed_changed = ati18800_speed_changed, + .force_redraw = ati18800_force_redraw, + .config = NULL +}; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index d4abebb39c4..626ddeca950 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -41,7 +41,6 @@ void ega_doblit(int wx, int wy, ega_t *ega); #define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" #define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" #define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" -#define BIOS_ATIEGA_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" #define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" #define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" @@ -49,7 +48,6 @@ enum { EGA_IBM = 0, EGA_COMPAQ, EGA_SUPEREGA, - EGA_ATI, EGA_ISKRA, EGA_TSENG }; @@ -80,34 +78,6 @@ ega_out(uint16_t addr, uint8_t val, void *priv) addr ^= 0x60; switch (addr) { - case 0x1ce: - ega->index = val; - break; - case 0x1cf: - ega->regs[ega->index] = val; - switch (ega->index) { - case 0xb0: - ega_recalctimings(ega); - break; - case 0xb2: - case 0xbe: -#if 0 - if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ - svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; -#endif - break; - case 0xb3: - ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); - break; - - default: - break; - } - break; - case 0x3c0: case 0x3c1: if (!ega->attrff) { @@ -276,23 +246,6 @@ ega_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { - case 0x1ce: - ret = ega->index; - break; - case 0x1cf: - switch (ega->index) { - case 0xb7: - ret = ega->regs[ega->index] & ~8; - if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) - ret |= 8; - break; - - default: - ret = ega->regs[ega->index]; - break; - } - break; - case 0x3c0: if (ega_type) ret = ega->attraddr | ega->attr_palette_enable; @@ -476,31 +429,6 @@ ega_recalctimings(ega_t *ega) crtcconst *= 9.0; else crtcconst *= 8.0; - } else if (ega->eeprom) { - clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); - - switch (clksel) { - case 0: - crtcconst = (cpuclock / 25175000.0 * (double) (1ULL << 32)); - break; - case 1: - crtcconst = (cpuclock / 28322000.0 * (double) (1ULL << 32)); - break; - case 4: - crtcconst = (cpuclock / 14318181.0 * (double) (1ULL << 32)); - break; - case 5: - crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32)); - break; - case 7: - default: - crtcconst = (cpuclock / 36000000.0 * (double) (1ULL << 32)); - break; - } - if (!(ega->seqregs[1] & 1)) - crtcconst *= 9.0; - else - crtcconst *= 8.0; } else { if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); @@ -1414,10 +1342,6 @@ ega_standalone_init(const device_t *info) rom_init(&ega->bios_rom, BIOS_SEGA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; - case EGA_ATI: - rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; case EGA_ISKRA: rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -1445,12 +1369,7 @@ ega_standalone_init(const device_t *info) mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if (info->local == EGA_ATI) { - io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - ega->eeprom = malloc(sizeof(ati_eeprom_t)); - memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); - ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0); - } else if (info->local == EGA_COMPAQ) { + if (info->local == EGA_COMPAQ) { io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1478,12 +1397,6 @@ sega_standalone_available(void) return rom_present(BIOS_SEGA_PATH); } -static int -atiega_standalone_available(void) -{ - return rom_present(BIOS_ATIEGA_PATH); -} - static int iskra_ega_standalone_available(void) { @@ -1501,8 +1414,6 @@ ega_close(void *priv) { ega_t *ega = (ega_t *) priv; - if (ega->eeprom) - free(ega->eeprom); free(ega->vram); free(ega); } @@ -1640,20 +1551,6 @@ const device_t sega_device = { .config = ega_config }; -const device_t atiega_device = { - .name = "ATI EGA Wonder 800+", - .internal_name = "egawonder800", - .flags = DEVICE_ISA, - .local = EGA_ATI, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, - { .available = atiega_standalone_available }, - .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config -}; - const device_t iskra_ega_device = { .name = "Iskra EGA (Cyrillic ROM)", .internal_name = "iskra_ega", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 6317fb5a326..f7f377888b4 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -79,7 +79,7 @@ video_cards[] = { // clang-format off { &vid_none_device }, { &vid_internal_device }, - { &atiega_device }, + { &ati18800_egawonder800plus_device }, { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, From 0bd67a1bc4517a1d1f5d8ab086cfe8fe672f8ab6 Mon Sep 17 00:00:00 2001 From: GreaseMonkey Date: Tue, 19 Dec 2023 13:11:01 +1300 Subject: [PATCH 030/146] Report correct S3 Trio64V2/DX revision ID Doesn't seem to affect much, but we might as well fix it. --- src/video/vid_s3.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 35e65cc182d..9a56acdd7db 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -2934,8 +2934,14 @@ s3_in(uint16_t addr, void *priv) return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ case 0x2e: return s3->id_ext; /*New chip ID*/ - case 0x2f: - return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision level*/ + case 0x2f: switch (s3->chip) { /*Revision level*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; + } case 0x30: return s3->id; /*Chip ID*/ case 0x31: @@ -7558,8 +7564,14 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ - case 0x08: - return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision ID*/ + case 0x08: switch (s3->chip) { /*Revision ID*/ + case S3_TRIO64V: + return 0x40; + case S3_TRIO64V2: + return 0x16; /*Confirmed on an onboard 64V2/DX*/ + default: + return 0x00; + } case 0x09: return 0; /*Programming interface*/ From efe9784aad8dfc742330ae20e95d550ecc3c2574 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 11:42:01 +0600 Subject: [PATCH 031/146] MGA: Count for cases where DMA header data is not immediately available Fixes crashes on NT 4.0 --- src/video/vid_mga.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2c9561b020b..2d4d3be020a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,6 +15,7 @@ * Copyright 2008-2020 Sarah Walker. */ #include +#include #include #include #include @@ -512,6 +513,8 @@ typedef struct mystique_t { pri_header, sec_header, iload_header; + bool words_expected, sec_words_expected; + mutex_t *lock; } dma; @@ -2664,13 +2667,21 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { + if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK) && !mystique->dma.words_expected) + { + /* Wait until more data is available. */ + mystique->dma.words_expected = 1; + break; + } + + mystique->dma.words_expected = 0; + if ((mystique->dma.pri_header & 0xff) != 0x15) { uint32_t val; uint32_t reg_addr; @@ -2709,7 +2720,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.sec_state == 0) { + if (mystique->dma.sec_state == 0 && !mystique->dma.sec_words_expected) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; words_transferred++; @@ -2718,6 +2729,14 @@ run_dma(mystique_t *mystique) uint32_t val; uint32_t reg_addr; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK) && !mystique->dma.sec_words_expected) + { + /* Wait until more data is available. */ + mystique->dma.sec_words_expected = 1; + break; + } + + mystique->dma.sec_words_expected = 0; dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; From 3ba6e337c5cc0ca61357e9b97ceb867c1db67e5d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 12:02:58 +0600 Subject: [PATCH 032/146] Revert "MGA: Count for cases where DMA header data is not immediately available" This reverts commit efe9784aad8dfc742330ae20e95d550ecc3c2574. --- src/video/vid_mga.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2d4d3be020a..2c9561b020b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,7 +15,6 @@ * Copyright 2008-2020 Sarah Walker. */ #include -#include #include #include #include @@ -513,8 +512,6 @@ typedef struct mystique_t { pri_header, sec_header, iload_header; - bool words_expected, sec_words_expected; - mutex_t *lock; } dma; @@ -2667,21 +2664,13 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { + if (mystique->dma.pri_state == 0) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; words_transferred++; } - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK) && !mystique->dma.words_expected) - { - /* Wait until more data is available. */ - mystique->dma.words_expected = 1; - break; - } - - mystique->dma.words_expected = 0; - if ((mystique->dma.pri_header & 0xff) != 0x15) { + if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { uint32_t val; uint32_t reg_addr; @@ -2720,7 +2709,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.sec_state == 0 && !mystique->dma.sec_words_expected) { + if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; words_transferred++; @@ -2729,14 +2718,6 @@ run_dma(mystique_t *mystique) uint32_t val; uint32_t reg_addr; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK) && !mystique->dma.sec_words_expected) - { - /* Wait until more data is available. */ - mystique->dma.sec_words_expected = 1; - break; - } - - mystique->dma.sec_words_expected = 0; dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; From 1f91c0e2ec22d0122f15cb12e754ccbbdd0f4eb1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 12:59:18 +0600 Subject: [PATCH 033/146] More work on busmastering NT 4.0 freezes as of now. No idea, although the data aren't filled with total nonsense anymore --- src/video/vid_mga.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2c9561b020b..1cba098ef8c 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -512,6 +512,8 @@ typedef struct mystique_t { pri_header, sec_header, iload_header; + atomic_uint words_expected; + mutex_t *lock; } dma; @@ -2435,7 +2437,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->status &= ~STATUS_ENDPRDMASTS; mystique->dma.state = DMA_STATE_PRI; - mystique->dma.pri_state = 0; + //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } thread_release_mutex(mystique->dma.lock); @@ -2664,19 +2666,32 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; + } + if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; + pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); + mystique->dma.words_expected = 4; words_transferred++; } - if ((mystique->dma.pri_header & 0xff) != 0x15 && (mystique->dma.primaddress & DMA_ADDR_MASK) < (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + break; + } + + if ((mystique->dma.pri_header & 0xff) != 0x15) { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); - mystique->dma.primaddress += 4; words_transferred++; + pclog("DMA val: 0x%08X\n", val); reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2690,6 +2705,10 @@ run_dma(mystique_t *mystique) mystique_accel_ctrl_write_l(reg_addr, val, mystique); } + if (mystique->dma.words_expected) + mystique->dma.words_expected--; + mystique->dma.primaddress += 4; + mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; @@ -2740,8 +2759,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else + } else{ mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } break; @@ -2760,8 +2782,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else + } else { mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } } } break; From 3a5bbe9ad391bfb7647b863714fe6f25ae51ca1d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 13:46:27 +0600 Subject: [PATCH 034/146] vid_mga: Busmastering works properly now --- src/video/vid_mga.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 1cba098ef8c..bf73206dc0a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2674,7 +2674,6 @@ run_dma(mystique_t *mystique) if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); mystique->dma.primaddress += 4; - pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); mystique->dma.words_expected = 4; words_transferred++; } @@ -2685,13 +2684,12 @@ run_dma(mystique_t *mystique) break; } - if ((mystique->dma.pri_header & 0xff) != 0x15) { + { uint32_t val; uint32_t reg_addr; dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); words_transferred++; - pclog("DMA val: 0x%08X\n", val); reg_addr = (mystique->dma.pri_header & 0x7f) << 2; if (mystique->dma.pri_header & 0x80) @@ -2712,8 +2710,10 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - if (mystique->dma.state == DMA_STATE_SEC) - mystique->dma.pri_state = 0; + if (mystique->dma.state == DMA_STATE_SEC) { + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; From 8226a5e39c689a83449e2932b8c674cfb60859ff Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 16:27:05 +0600 Subject: [PATCH 035/146] Matrox Mystique: Attempt fixing 3D busmastered drawing NT 4.0's OpenGL screensavers only display one frame before freezing the system --- src/video/vid_mga.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bf73206dc0a..3fd1435476d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2064,6 +2064,12 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) mystique->blitter_complete_refcount = 0; mystique->dwgreg.iload_rem_count = 0; mystique->status = STATUS_ENDPRDMASTS; + thread_wait_mutex(mystique->dma.lock); + mystique->dma.pri_state = 0; + mystique->dma.sec_state = 0; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + thread_release_mutex(mystique->dma.lock); break; case REG_ATTR_IDX: @@ -2393,6 +2399,8 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_SOFTRAP: mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; mystique->softrap_pending_val = val; mystique->softrap_pending = 1; @@ -2713,6 +2721,7 @@ run_dma(mystique_t *mystique) if (mystique->dma.state == DMA_STATE_SEC) { mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; + mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; @@ -2728,6 +2737,18 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; @@ -2759,7 +2780,9 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; - } else{ + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { mystique->dma.state = DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; @@ -2770,6 +2793,18 @@ run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { uint32_t val; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); mystique->dma.secaddress += 4; @@ -2782,6 +2817,8 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; } else { mystique->dma.state = DMA_STATE_PRI; mystique->dma.words_expected = 0; From 1e71efc5bb9d24c9c761614c98102a36a1d7cdc4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 19 Dec 2023 18:48:49 +0100 Subject: [PATCH 036/146] More MGA fixes. Re-introduced the mystique read/write linear functions but with a check (!svga->fast) in the byte ones to make sure the generic svga linear functions are enabled when needed, this should keep compatibility stable while also fixing the amount of memory of NT 4.0's MGA Millennium drivers. --- src/video/vid_mga.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index bf73206dc0a..d6b07c68b54 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -636,14 +636,12 @@ static void wake_fifo_thread(mystique_t *mystique); static void wait_fifo_idle(mystique_t *mystique); static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv); static uint16_t mystique_readw_linear(uint32_t addr, void *priv); static uint32_t mystique_readl_linear(uint32_t addr, void *priv); static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *priv); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *priv); -#endif static void mystique_recalc_mapping(mystique_t *mystique); static int mystique_line_compare(svga_t *svga); @@ -994,7 +992,7 @@ mystique_recalc_mapping(mystique_t *mystique) if (mystique->pci_regs[0x41] & 1) { switch (svga->gdcreg[6] & 0x0C) { case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); svga->banked_mask = 0x1ffff; break; case 0x4: /*64k at A0000*/ @@ -2560,12 +2558,14 @@ mystique_accel_iload_write_l(UNUSED(uint32_t addr), uint32_t val, void *priv) } } -#if 0 static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { const svga_t *svga = (svga_t *) priv; + if (!svga->fast) + return svga_read_linear(addr, priv); + cycles -= video_timing_read_b; addr &= svga->decode_mask; @@ -2608,6 +2608,11 @@ mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + if (!svga->fast) { + svga_write_linear(addr, val, priv); + return; + } + cycles -= video_timing_write_b; addr &= svga->decode_mask; @@ -2647,7 +2652,6 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) svga->changedvram[addr >> 12] = svga->monitor->mon_changeframecount; *(uint32_t *) &svga->vram[addr] = val; } -#endif static void run_dma(mystique_t *mystique) @@ -2711,7 +2715,7 @@ run_dma(mystique_t *mystique) mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; if (mystique->dma.state == DMA_STATE_SEC) { - mystique->dma.pri_state = 0; + mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { @@ -5652,8 +5656,8 @@ mystique_init(const device_t *info) mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear, + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, NULL, 0, &mystique->svga); mem_mapping_disable(&mystique->lfb_mapping); From d38ad2eb23fc2e9611933a7800239bb8f9b99878 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 19 Dec 2023 19:03:54 +0100 Subject: [PATCH 037/146] ATI EGA Wonder 800+ fixes. 1. Reverted the migration from ATI 18800 as the EGA code had the proper palette. 2. Add support for the 800x600 resolution required by said card. --- src/include/86box/vid_ega.h | 5 ++ src/include/86box/video.h | 1 - src/video/vid_ati18800.c | 71 +--------------- src/video/vid_ega.c | 158 +++++++++++++++++++++++++++++++++--- src/video/vid_table.c | 2 +- 5 files changed, 155 insertions(+), 82 deletions(-) diff --git a/src/include/86box/vid_ega.h b/src/include/86box/vid_ega.h index ec13de928cc..ec241d613ab 100644 --- a/src/include/86box/vid_ega.h +++ b/src/include/86box/vid_ega.h @@ -109,6 +109,8 @@ typedef struct ega_t { int bpp; int index; int remap_required; + int actual_type; + int chipset; uint32_t charseta; uint32_t charsetb; @@ -132,6 +134,8 @@ typedef struct ega_t { double dot_clock; + void * eeprom; + uint32_t (*remap_func)(struct ega_t *ega, uint32_t in_addr); void (*render)(struct ega_t *svga); } ega_t; @@ -141,6 +145,7 @@ typedef struct ega_t { extern const device_t ega_device; extern const device_t cpqega_device; extern const device_t sega_device; +extern const device_t atiega800p_device; extern const device_t iskra_ega_device; extern const device_t et2000_device; #endif diff --git a/src/include/86box/video.h b/src/include/86box/video.h index de27fcbb1fa..396b391241d 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -322,7 +322,6 @@ extern const device_t ati18800_wonder_device; # endif extern const device_t ati18800_vga88_device; extern const device_t ati18800_device; -extern const device_t ati18800_egawonder800plus_device; /* ATi 28800 */ extern const device_t ati28800_device; diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index fd658eacfbf..f9dc8821ec4 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -37,18 +37,15 @@ #endif #define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" #define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" -#define BIOS_ROM_PATH_ATIEGAPLUS "roms/video/ati18800/ATI EGA Wonder 800+ N1.00.BIN" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) ATI18800_WONDER = 0, ATI18800_VGA88, - ATI18800_EDGE16, - ATI18800_EGAWONDER800PLUS + ATI18800_EDGE16 #else ATI18800_VGA88 = 0, - ATI18800_EDGE16, - ATI18800_EGAWONDER800PLUS + ATI18800_EDGE16 #endif }; @@ -71,6 +68,7 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) { ati18800_t *ati18800 = (ati18800_t *) priv; svga_t *svga = &ati18800->svga; + uint8_t o; uint8_t old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -182,40 +180,6 @@ ati18800_recalctimings(svga_t *svga) clock_sel = ((svga->miscout >> 2) & 3) | ((ati18800->regs[0xbe] & 0x10) >> 1) | ((ati18800->regs[0xb9] & 2) << 1); - if (ati18800->type == ATI18800_EGAWONDER800PLUS) { - svga->crtc[5] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ - svga->crtc[0x0b] &= ~0x60; /*Not supported by the EGA Wonder 800+*/ - - svga->hdisp_time = svga->hdisp; - - svga->hdisp = svga->crtc[1]; - svga->hdisp++; - - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]); - - svga->hdisp_time = svga->hdisp; - svga->render = svga_render_blank; - - if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { /*40 column*/ - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - /* Character clock is off by 1 now in 40-line modes, on all cards. */ - svga->ma_latch--; - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - } else { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; - } - svga->hdisp_old = svga->hdisp; - } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->hdisp_old = svga->hdisp; - } - } - } - if (ati18800->regs[0xb6] & 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; @@ -291,10 +255,6 @@ ati18800_init(const device_t *info) rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); ati18800->memory = 512; break; - case ATI18800_EGAWONDER800PLUS: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_ATIEGAPLUS, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - ati18800->memory = 256; - break; } svga_init(info, &ati18800->svga, ati18800, ati18800->memory << 10, @@ -311,10 +271,7 @@ ati18800_init(const device_t *info) ati18800->svga.miscout = 1; ati18800->svga.bpp = 8; - if (info->local == ATI18800_EGAWONDER800PLUS) - ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); - else - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); return ati18800; } @@ -339,12 +296,6 @@ ati18800_available(void) return rom_present(BIOS_ROM_PATH_EDGE16); } -static int -ati18800_egawonder800plus_available(void) -{ - return rom_present(BIOS_ROM_PATH_ATIEGAPLUS); -} - static void ati18800_close(void *priv) { @@ -414,17 +365,3 @@ const device_t ati18800_device = { .force_redraw = ati18800_force_redraw, .config = NULL }; - -const device_t ati18800_egawonder800plus_device = { - .name = "ATI EGA Wonder 800+", - .internal_name = "egawonder800", - .flags = DEVICE_ISA, - .local = ATI18800_EGAWONDER800PLUS, - .init = ati18800_init, - .close = ati18800_close, - .reset = NULL, - { .available = ati18800_egawonder800plus_available }, - .speed_changed = ati18800_speed_changed, - .force_redraw = ati18800_force_redraw, - .config = NULL -}; diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 626ddeca950..da77449b0b5 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -41,6 +41,7 @@ void ega_doblit(int wx, int wy, ega_t *ega); #define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" #define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" #define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" +#define BIOS_ATIEGA800P_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" #define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" #define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" @@ -48,6 +49,7 @@ enum { EGA_IBM = 0, EGA_COMPAQ, EGA_SUPEREGA, + EGA_ATI800P, EGA_ISKRA, EGA_TSENG }; @@ -78,6 +80,24 @@ ega_out(uint16_t addr, uint8_t val, void *priv) addr ^= 0x60; switch (addr) { + case 0x1ce: + ega->index = val; + break; + case 0x1cf: + ega->regs[ega->index] = val; + switch (ega->index) { + case 0xb0: + ega_recalctimings(ega); + break; + case 0xb3: + ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); + break; + + default: + break; + } + break; + case 0x3c0: case 0x3c1: if (!ega->attrff) { @@ -126,8 +146,7 @@ ega_out(uint16_t addr, uint8_t val, void *priv) io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); if (!(val & 1)) io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if ((o ^ val) & 0x80) - ega_recalctimings(ega); + ega_recalctimings(ega); break; case 0x3c4: ega->seqaddr = val; @@ -208,14 +227,24 @@ ega_out(uint16_t addr, uint8_t val, void *priv) break; case 0x3d0: case 0x3d4: - ega->crtcreg = val & 31; + if (ega->chipset) + ega->crtcreg = val & 0x3f; + else + ega->crtcreg = val & 0x1f; return; case 0x3d1: case 0x3d5: - if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) - return; - if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) - val = (ega->crtc[7] & ~0x10) | (val & 0x10); + if (ega->chipset) { + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80) && !(ega->regs[0xb4] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + } else { + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + } old = ega->crtc[ega->crtcreg]; ega->crtc[ega->crtcreg] = val; if (old != val) { @@ -246,6 +275,23 @@ ega_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { + case 0x1ce: + ret = ega->index; + break; + case 0x1cf: + switch (ega->index) { + case 0xb7: + ret = ega->regs[ega->index] & ~8; + if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) + ret |= 8; + break; + + default: + ret = ega->regs[ega->index]; + break; + } + break; + case 0x3c0: if (ega_type) ret = ega->attraddr | ega->attr_palette_enable; @@ -255,8 +301,8 @@ ega_in(uint16_t addr, void *priv) ret = ega->attrregs[ega->attraddr]; break; case 0x3c2: - ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; - break; + ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; + break; case 0x3c4: if (ega_type) ret = ega->seqaddr; @@ -310,6 +356,7 @@ ega_in(uint16_t addr, void *priv) default: if (ega_type) ret = ega->crtc[ega->crtcreg]; + break; } break; case 0x3da: @@ -429,6 +476,31 @@ ega_recalctimings(ega_t *ega) crtcconst *= 9.0; else crtcconst *= 8.0; + } else if (ega->eeprom) { + clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); + + switch (clksel) { + case 0: + crtcconst = (cpuclock / 25175000.0 * (double) (1ULL << 32)); + break; + case 1: + crtcconst = (cpuclock / 28322000.0 * (double) (1ULL << 32)); + break; + case 4: + crtcconst = (cpuclock / 14318181.0 * (double) (1ULL << 32)); + break; + case 5: + crtcconst = (cpuclock / 16257000.0 * (double) (1ULL << 32)); + break; + case 7: + default: + crtcconst = (cpuclock / 36000000.0 * (double) (1ULL << 32)); + break; + } + if (!(ega->seqregs[1] & 1)) + crtcconst *= 9.0; + else + crtcconst *= 8.0; } else { if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); @@ -460,6 +532,15 @@ ega_recalctimings(ega_t *ega) } } + if (ega->chipset) { + if (ega->hdisp > 640) { + ega->dispend <<= 1; + ega->vtotal <<= 1; + ega->split <<= 1; + ega->vsyncstart <<= 1; + } + } + if (enable_overscan) { overscan_y = (ega->rowcount + 1) << 1; @@ -663,8 +744,18 @@ ega_poll(void *priv) if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) ega->stat &= ~8; ega->vslines++; - if (ega->displine > 500) - ega->displine = 0; + if (ega->chipset) { + if (ega->hdisp > 640) { + if (ega->displine > 2000) + ega->displine = 0; + } else { + if (ega->displine > 500) + ega->displine = 0; + } + } else { + if (ega->displine > 500) + ega->displine = 0; + } } else { timer_advance_u64(&ega->timer, ega->dispontime); @@ -700,7 +791,13 @@ ega_poll(void *priv) } } ega->vc++; - ega->vc &= 511; + if (ega->chipset) { + if (ega->hdisp > 640) + ega->vc &= 1023; + else + ega->vc &= 511; + } else + ega->vc &= 511; if (ega->vc == ega->split) { // TODO: Implement the hardware bug where the first scanline is drawn twice when the split happens if (ega->interlace && ega->oddeven) @@ -1327,6 +1424,9 @@ ega_standalone_init(const device_t *info) else ega_type = 1; + ega->actual_type = info->local; + ega->chipset = 0; + switch (info->local) { default: case EGA_IBM: @@ -1342,6 +1442,11 @@ ega_standalone_init(const device_t *info) rom_init(&ega->bios_rom, BIOS_SEGA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; + case EGA_ATI800P: + rom_init(&ega->bios_rom, BIOS_ATIEGA800P_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ega->chipset = 1; + break; case EGA_ISKRA: rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -1369,7 +1474,12 @@ ega_standalone_init(const device_t *info) mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if (info->local == EGA_COMPAQ) { + if (ega->chipset) { + io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + ega->eeprom = malloc(sizeof(ati_eeprom_t)); + memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); + ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800p.nvr", 0); + } else if (info->local == EGA_COMPAQ) { io_sethandler(0x0084, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x07c6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x0bc6, 0x0001, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); @@ -1397,6 +1507,12 @@ sega_standalone_available(void) return rom_present(BIOS_SEGA_PATH); } +static int +atiega800p_standalone_available(void) +{ + return rom_present(BIOS_ATIEGA800P_PATH); +} + static int iskra_ega_standalone_available(void) { @@ -1414,6 +1530,8 @@ ega_close(void *priv) { ega_t *ega = (ega_t *) priv; + if (ega->eeprom) + free(ega->eeprom); free(ega->vram); free(ega); } @@ -1551,6 +1669,20 @@ const device_t sega_device = { .config = ega_config }; +const device_t atiega800p_device = { + .name = "ATI EGA Wonder 800+", + .internal_name = "egawonder800p", + .flags = DEVICE_ISA, + .local = EGA_ATI800P, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, + { .available = atiega800p_standalone_available }, + .speed_changed = ega_speed_changed, + .force_redraw = NULL, + .config = ega_config +}; + const device_t iskra_ega_device = { .name = "Iskra EGA (Cyrillic ROM)", .internal_name = "iskra_ega", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index f7f377888b4..0131fa3a442 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -79,7 +79,7 @@ video_cards[] = { // clang-format off { &vid_none_device }, { &vid_internal_device }, - { &ati18800_egawonder800plus_device }, + { &atiega800p_device }, { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, From 7495c2537b5fa4ce698aa471801ba621ca0efb2c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Dec 2023 19:32:23 +0100 Subject: [PATCH 038/146] Fixed a warning in video/vid_ati18800.c. --- src/video/vid_ati18800.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index f9dc8821ec4..09e813babf4 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -68,7 +68,6 @@ ati18800_out(uint16_t addr, uint8_t val, void *priv) { ati18800_t *ati18800 = (ati18800_t *) priv; svga_t *svga = &ati18800->svga; - uint8_t o; uint8_t old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) From c64748ca6cf7a54e38be0617320898f07359bc79 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Dec 2023 20:02:07 +0100 Subject: [PATCH 039/146] Slight RTL8139 mapping fixes, now Windows 2000 pings correctly, but still all 00's MAC address. --- src/network/net_rtl8139.c | 74 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 6c86bdebfbe..942eb9be7a9 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -490,6 +490,8 @@ struct RTL8139State { int cplus_txbuffer_len; int cplus_txbuffer_offset; + uint32_t mem_base; + /* PCI interrupt timer */ pc_timer_t timer; @@ -3151,6 +3153,72 @@ rtl8139_io_writeb_ioport(uint16_t addr, uint8_t val, void *priv) return rtl8139_io_writeb(addr, val, priv); } +static uint32_t +rtl8139_io_readl_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return 0xffffffff; + + return rtl8139_io_readl(addr, priv); +} + +static uint16_t +rtl8139_io_readw_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return 0xffff; + + return rtl8139_io_readw(addr, priv); +} + +static uint8_t +rtl8139_io_readb_mem(uint32_t addr, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return 0xff; + + return rtl8139_io_readb(addr, priv); +} + +static void +rtl8139_io_writel_mem(uint32_t addr, uint32_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return; + + return rtl8139_io_writel(addr, val, priv); +} + +static void +rtl8139_io_writew_mem(uint32_t addr, uint16_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return; + + return rtl8139_io_writew(addr, val, priv); +} + +static void +rtl8139_io_writeb_mem(uint32_t addr, uint8_t val, void *priv) +{ + RTL8139State *s = (RTL8139State *) priv; + + if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) + return; + + return rtl8139_io_writeb(addr, val, priv); +} + static int rtl8139_set_link_status(void *priv, uint32_t link_state) { @@ -3286,6 +3354,7 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) case 0x16: case 0x17: s->pci_conf[addr & 0xFF] = val; + s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24); if (s->pci_conf[0x4] & PCI_COMMAND_MEM) mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); break; @@ -3304,7 +3373,10 @@ nic_init(const device_t *info) uint8_t *mac_bytes; uint32_t mac; - mem_mapping_add(&s->bar_mem, 0, 0, rtl8139_io_readb, rtl8139_io_readw, rtl8139_io_readl, rtl8139_io_writeb, rtl8139_io_writew, rtl8139_io_writel, NULL, MEM_MAPPING_EXTERNAL, s); + mem_mapping_add(&s->bar_mem, 0, 0, + rtl8139_io_readb_mem, rtl8139_io_readw_mem, rtl8139_io_readl_mem, + rtl8139_io_writeb_mem, rtl8139_io_writew_mem, rtl8139_io_writel_mem, + NULL, MEM_MAPPING_EXTERNAL, s); pci_add_card(PCI_ADD_NORMAL, rtl8139_pci_read, rtl8139_pci_write, s, &s->pci_slot); s->inst = device_get_instance(); From 1201b52890c5ef7ec78b270aaa3a252a66707b38 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Dec 2023 20:09:00 +0100 Subject: [PATCH 040/146] Fixed the RTL8139 MAC address. --- src/network/net_rtl8139.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 942eb9be7a9..afc73a0dda7 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3427,6 +3427,9 @@ nic_init(const device_t *info) mac_bytes[5] = (mac & 0xff); } + for (uint32_t i = 0; i < 6; i++) + s->phys[MAC0 + i] = mac_bytes[i]; + s->nic = network_attach(s, (uint8_t *) &s->eeprom.contents[7], rtl8139_do_receive, rtl8139_set_link_status); timer_add(&s->timer, rtl8139_timer, s, 0); timer_on_auto(&s->timer, 1000000.0 / cpu_pci_speed); From 1773ebfbf3dbc5b53be4662c4f9d6997b8d85c86 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 20 Dec 2023 01:30:09 +0600 Subject: [PATCH 041/146] Mystique: SOFTRAP register writes correctly reset the primary DMA channel --- src/video/vid_mga.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index a3838ea5965..8600fac3ec8 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2685,6 +2685,7 @@ run_dma(mystique_t *mystique) } if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); + //pclog("DMA header: 0x%08X\n", mystique->dma.pri_header); mystique->dma.primaddress += 4; mystique->dma.words_expected = 4; words_transferred++; @@ -2712,7 +2713,12 @@ run_dma(mystique_t *mystique) if ((reg_addr & 0x300) == 0x100) mystique->blitter_submit_dma_refcount++; + //pclog("DMA value: 0x%08X to reg 0x%04X\n", val, reg_addr); mystique_accel_ctrl_write_l(reg_addr, val, mystique); + if (reg_addr == REG_SOFTRAP) { + mystique->dma.primaddress += 4; + break; + } } if (mystique->dma.words_expected) @@ -2723,8 +2729,6 @@ run_dma(mystique_t *mystique) mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; if (mystique->dma.state == DMA_STATE_SEC) { - mystique->dma.pri_state = 0; - mystique->dma.words_expected = 0; mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { @@ -2756,9 +2760,23 @@ run_dma(mystique_t *mystique) if (mystique->dma.sec_state == 0) { dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); mystique->dma.secaddress += 4; + //pclog("DMA header (secondary): 0x%08X\n", mystique->dma.sec_header); words_transferred++; } + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; + } else { + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.words_expected = 0; + mystique->dma.pri_state = 0; + } + } + uint32_t val; uint32_t reg_addr; @@ -2775,7 +2793,7 @@ run_dma(mystique_t *mystique) mystique->blitter_submit_dma_refcount++; mystique_accel_ctrl_write_l(reg_addr, val, mystique); - + //pclog("DMA value (secondary): 0x%08X\n", val); mystique->dma.sec_header >>= 8; mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; From bf30678d5f48337db5125390d6a72754b436b750 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 20 Dec 2023 13:48:45 +0600 Subject: [PATCH 042/146] MGA: More Mystique busmastering fixes * Use mutex locking when reporting SOFTRAPEN * IEN register now correctly returns values it currently holds * Restore VLINEPEN interrupt --- src/video/vid_mga.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8600fac3ec8..c00c7693b4b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1032,6 +1032,8 @@ mystique_update_irqs(mystique_t *mystique) if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) irq = 1; + if ((mystique->status & mystique->ien) & STATUS_VLINEPEN) + irq = 1; if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) irq = 1; @@ -1442,7 +1444,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) break; case REG_IEN: - ret = mystique->ien & 0x64; + ret = mystique->ien & 0x65; break; case REG_IEN + 1: case REG_IEN + 2: @@ -1985,6 +1987,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) switch (addr & 0x3fff) { case REG_ICLEAR: if (val & ICLEAR_SOFTRAPICLR) { + //pclog("softrapiclr\n"); mystique->status &= ~STATUS_SOFTRAPEN; mystique_update_irqs(mystique); } @@ -2401,7 +2404,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; mystique->softrap_pending_val = val; - mystique->softrap_pending = 1; + mystique->softrap_pending += 1; break; default: @@ -2959,16 +2962,21 @@ mystique_softrap_pending_timer(void *priv) timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); - if (mystique->endprdmasts_pending) { - mystique->endprdmasts_pending = 0; - mystique->status |= STATUS_ENDPRDMASTS; - } - if (mystique->softrap_pending) { - mystique->softrap_pending = 0; + if (thread_test_mutex(mystique->dma.lock)) + { + if (mystique->endprdmasts_pending) { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; + } + if (mystique->softrap_pending) { + mystique->softrap_pending--; - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - mystique_update_irqs(mystique); + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + //pclog("softrapen\n"); + mystique_update_irqs(mystique); + } + thread_release_mutex(mystique->dma.lock); } } From 7a8fe414c5f0196670945a1c1f0fa8da41fe1e18 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 20 Dec 2023 16:19:29 +0600 Subject: [PATCH 043/146] MGA: 3D busmastering now works (albeit slowly) --- src/video/vid_mga.c | 48 ++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c00c7693b4b..d0ec17bffae 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2672,6 +2672,11 @@ run_dma(mystique_t *mystique) thread_wait_mutex(mystique->dma.lock); if (mystique->dma.state == DMA_STATE_IDLE) { + if (!(mystique->status & STATUS_ENDPRDMASTS)) + { + /* Force this to appear. */ + mystique->endprdmasts_pending = 1; + } thread_release_mutex(mystique->dma.lock); return; } @@ -2872,13 +2877,13 @@ fifo_thread(void *priv) mystique_t *mystique = (mystique_t *) priv; while (mystique->thread_run) { + int words_transferred = 0; thread_set_event(mystique->fifo_not_full_event); thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { - int words_transferred = 0; - + words_transferred = 0; while (!FIFO_EMPTY && words_transferred < 100) { fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; @@ -2905,13 +2910,13 @@ fifo_thread(void *priv) words_transferred++; } - - /*Only run DMA once the FIFO is empty. Required by - Screamer 2 / Rally which will incorrectly clip an ILOAD - if DMA runs ahead*/ - if (!words_transferred) - run_dma(mystique); } + + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); } } @@ -2962,22 +2967,21 @@ mystique_softrap_pending_timer(void *priv) timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); - if (thread_test_mutex(mystique->dma.lock)) - { - if (mystique->endprdmasts_pending) { - mystique->endprdmasts_pending = 0; - mystique->status |= STATUS_ENDPRDMASTS; - } - if (mystique->softrap_pending) { - mystique->softrap_pending--; + if (mystique->endprdmasts_pending) { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; + } + if (mystique->softrap_pending) { + mystique->softrap_pending--; - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - //pclog("softrapen\n"); - mystique_update_irqs(mystique); - } - thread_release_mutex(mystique->dma.lock); + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + //pclog("softrapen\n"); + mystique_update_irqs(mystique); } + /* Force ENDPRDMASTS flag to be set. */ + if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS)) + wake_fifo_thread(mystique); } static void From aabbad31d86289f991068ad5c8fe389db7d1700d Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Wed, 20 Dec 2023 15:28:32 +0500 Subject: [PATCH 044/146] qt: Set the window icon per-application, instead of per-window --- src/qt/qt_main.cpp | 11 +++++++++++ src/qt/qt_mainwindow.cpp | 9 --------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c859fe033ce..1d6526521e6 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -194,6 +194,17 @@ main(int argc, char *argv[]) QApplication::setFont(QFont(font_name, font_size.toInt())); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif + +#ifdef RELEASE_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); +#elif defined ALPHA_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); +#elif defined BETA_BUILD + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); +#else + app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); +#endif + if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index f3503caebf1..e0252dd7a90 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -196,15 +196,6 @@ MainWindow::MainWindow(QWidget *parent) auto toolbar_label = new QLabel(); ui->toolBar->addWidget(toolbar_label); -#ifdef RELEASE_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); -#elif defined ALPHA_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); -#elif defined BETA_BUILD - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); -#else - this->setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); -#endif this->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, vid_resize != 1); this->setWindowFlag(Qt::WindowMaximizeButtonHint, vid_resize == 1); From fdae410884246cf81c0226f44554ac24087b35f3 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:15:31 +0500 Subject: [PATCH 045/146] qt: Set the .desktop file name on *nix May fix generic icon instead of 86Box's icon showing up on Wayland --- src/qt/qt_main.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 1d6526521e6..02a0026d8b4 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -205,6 +205,10 @@ main(int argc, char *argv[]) app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); #endif +#if (!defined(Q_OS_WINDOWS) && !defined(__APPLE__)) + app.setDesktopFileName("net.86box.86Box"); +#endif + if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; From 04103ee9b1ec15f371be58e0fedae78cd770a313 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 20 Dec 2023 20:49:51 +0100 Subject: [PATCH 046/146] Made the RTL8139 use the same 93x6 EEPROM implementation as the DEC Tulip's, also cleaned up the I/O and memory access handlers a bit. --- src/network/net_rtl8139.c | 390 ++++++++++---------------------------- 1 file changed, 101 insertions(+), 289 deletions(-) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index afc73a0dda7..74a1f90ff3f 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -39,6 +39,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> +#include <86box/net_eeprom_nmc93cxx.h> #include <86box/bswap.h> #include <86box/nvr.h> #include "cpu.h" @@ -351,44 +352,6 @@ enum chip_flags { #define RTL8139_PCI_REVID RTL8139_PCI_REVID_8139CPLUS -/* Size is 64 * 16bit words */ -#define EEPROM_9346_ADDR_BITS 6 -#define EEPROM_9346_SIZE (1 << EEPROM_9346_ADDR_BITS) -#define EEPROM_9346_ADDR_MASK (EEPROM_9346_SIZE - 1) - -enum Chip9346Operation { - Chip9346_op_mask = 0xc0, /* 10 zzzzzz */ - Chip9346_op_read = 0x80, /* 10 AAAAAA */ - Chip9346_op_write = 0x40, /* 01 AAAAAA D(15)..D(0) */ - Chip9346_op_ext_mask = 0xf0, /* 11 zzzzzz */ - Chip9346_op_write_enable = 0x30, /* 00 11zzzz */ - Chip9346_op_write_all = 0x10, /* 00 01zzzz */ - Chip9346_op_write_disable = 0x00, /* 00 00zzzz */ -}; - -enum Chip9346Mode { - Chip9346_none = 0, - Chip9346_enter_command_mode, - Chip9346_read_command, - Chip9346_data_read, /* from output register */ - Chip9346_data_write, /* to input register, then to contents at specified address */ - Chip9346_data_write_all, /* to input register, then filling contents */ -}; - -typedef struct EEprom9346 { - uint16_t contents[EEPROM_9346_SIZE]; - int mode; - uint32_t tick; - uint8_t address; - uint16_t input; - uint16_t output; - - uint8_t eecs; - uint8_t eesk; - uint8_t eedi; - uint8_t eedo; -} EEprom9346; - #pragma pack(push, 1) typedef struct RTL8139TallyCounters { /* Tally counters */ @@ -476,8 +439,6 @@ struct RTL8139State { uint32_t RxRingAddrLO; uint32_t RxRingAddrHI; - EEprom9346 eeprom; - uint32_t TCTR; uint32_t TimerInt; int64_t TCTR_base; @@ -499,190 +460,14 @@ struct RTL8139State { /* Support migration to/from old versions */ int rtl8139_mmio_io_addr_dummy; + + nmc93cxx_eeprom_t *eeprom; + uint8_t eeprom_data[128]; }; /* Writes tally counters to memory via DMA */ static void RTL8139TallyCounters_dma_write(RTL8139State *s, uint32_t tc_addr); -static void -prom9346_decode_command(EEprom9346 *eeprom, uint8_t command) -{ - rtl8139_log("eeprom command 0x%02x\n", command); - - switch (command & Chip9346_op_mask) { - case Chip9346_op_read: - { - eeprom->address = command & EEPROM_9346_ADDR_MASK; - eeprom->output = eeprom->contents[eeprom->address]; - eeprom->eedo = 0; - eeprom->tick = 0; - eeprom->mode = Chip9346_data_read; - rtl8139_log("eeprom read from address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->output); - } - break; - - case Chip9346_op_write: - { - eeprom->address = command & EEPROM_9346_ADDR_MASK; - eeprom->input = 0; - eeprom->tick = 0; - eeprom->mode = Chip9346_none; /* Chip9346_data_write */ - rtl8139_log("eeprom begin write to address 0x%02x\n", - eeprom->address); - } - break; - default: - eeprom->mode = Chip9346_none; - switch (command & Chip9346_op_ext_mask) { - case Chip9346_op_write_enable: - rtl8139_log("eeprom write enabled\n"); - break; - case Chip9346_op_write_all: - rtl8139_log("eeprom begin write all\n"); - break; - case Chip9346_op_write_disable: - rtl8139_log("eeprom write disabled\n"); - break; - - default: - break; - } - break; - } -} - -static void -prom9346_shift_clock(EEprom9346 *eeprom) -{ - int bit = eeprom->eedi ? 1 : 0; - - ++eeprom->tick; - - rtl8139_log("eeprom: tick %d eedi=%d eedo=%d\n", eeprom->tick, eeprom->eedi, - eeprom->eedo); - - switch (eeprom->mode) { - case Chip9346_enter_command_mode: - if (bit) { - eeprom->mode = Chip9346_read_command; - eeprom->tick = 0; - eeprom->input = 0; - rtl8139_log("eeprom: +++ synchronized, begin command read\n"); - } - break; - - case Chip9346_read_command: - eeprom->input = (eeprom->input << 1) | (bit & 1); - if (eeprom->tick == 8) { - prom9346_decode_command(eeprom, eeprom->input & 0xff); - } - break; - - case Chip9346_data_read: - eeprom->eedo = (eeprom->output & 0x8000) ? 1 : 0; - eeprom->output <<= 1; - if (eeprom->tick == 16) { -#if 1 - // the FreeBSD drivers (rl and re) don't explicitly toggle - // CS between reads (or does setting Cfg9346 to 0 count too?), - // so we need to enter wait-for-command state here - eeprom->mode = Chip9346_enter_command_mode; - eeprom->input = 0; - eeprom->tick = 0; - - rtl8139_log("eeprom: +++ end of read, awaiting next command\n"); -#else - // original behaviour - ++eeprom->address; - eeprom->address &= EEPROM_9346_ADDR_MASK; - eeprom->output = eeprom->contents[eeprom->address]; - eeprom->tick = 0; - - rtl8139_log("eeprom: +++ read next address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->output); -#endif - } - break; - - case Chip9346_data_write: - eeprom->input = (eeprom->input << 1) | (bit & 1); - if (eeprom->tick == 16) { - rtl8139_log("eeprom write to address 0x%02x data=0x%04x\n", - eeprom->address, eeprom->input); - - eeprom->contents[eeprom->address] = eeprom->input; - eeprom->mode = Chip9346_none; /* waiting for next command after CS cycle */ - eeprom->tick = 0; - eeprom->input = 0; - } - break; - - case Chip9346_data_write_all: - eeprom->input = (eeprom->input << 1) | (bit & 1); - if (eeprom->tick == 16) { - for (int i = 0; i < EEPROM_9346_SIZE; i++) { - eeprom->contents[i] = eeprom->input; - } - rtl8139_log("eeprom filled with data=0x%04x\n", eeprom->input); - - eeprom->mode = Chip9346_enter_command_mode; - eeprom->tick = 0; - eeprom->input = 0; - } - break; - - default: - break; - } -} - -static int -prom9346_get_wire(RTL8139State *s) -{ - const EEprom9346 *eeprom = &s->eeprom; - if (!eeprom->eecs) - return 0; - - return eeprom->eedo; -} - -/* FIXME: This should be merged into/replaced by eeprom93xx.c. */ -static void -prom9346_set_wire(RTL8139State *s, int eecs, int eesk, int eedi) -{ - EEprom9346 *eeprom = &s->eeprom; - uint8_t old_eecs = eeprom->eecs; - uint8_t old_eesk = eeprom->eesk; - - eeprom->eecs = eecs; - eeprom->eesk = eesk; - eeprom->eedi = eedi; - - rtl8139_log("eeprom: +++ wires CS=%d SK=%d DI=%d DO=%d\n", eeprom->eecs, - eeprom->eesk, eeprom->eedi, eeprom->eedo); - - if (!old_eecs && eecs) { - /* Synchronize start */ - eeprom->tick = 0; - eeprom->input = 0; - eeprom->output = 0; - eeprom->mode = Chip9346_enter_command_mode; - - rtl8139_log("=== eeprom: begin access, enter command mode\n"); - } - - if (!eecs) { - rtl8139_log("=== eeprom: end access\n"); - return; - } - - if (!old_eesk && eesk) { - /* SK front rules */ - prom9346_shift_clock(eeprom); - } -} - static void rtl8139_update_irq(RTL8139State *s) { @@ -1436,9 +1221,8 @@ rtl8139_IntrMitigate_read(UNUSED(RTL8139State *s)) static int rtl8139_config_writable(RTL8139State *s) { - if ((s->Cfg9346 & Chip9346_op_mask) == Cfg9346_ConfigWrite) { + if ((s->Cfg9346 & 0xc0) == 0xc0) return 1; - } rtl8139_log("Configuration registers are write-protected\n"); @@ -1520,10 +1304,10 @@ rtl8139_Cfg9346_write(RTL8139State *s, uint32_t val) if (opmode == 0x80) { /* eeprom access */ - int eecs = (eeprom_val & 0x08) ? 1 : 0; - int eesk = (eeprom_val & 0x04) ? 1 : 0; - int eedi = (eeprom_val & 0x02) ? 1 : 0; - prom9346_set_wire(s, eecs, eesk, eedi); + nmc93cxx_eeprom_write(s->eeprom, + !!(eeprom_val & 0x08), + !!(eeprom_val & 0x04), + !!(eeprom_val & 0x02)); } else if (opmode == 0x40) { /* Reset. */ val = 0; @@ -1541,13 +1325,10 @@ rtl8139_Cfg9346_read(RTL8139State *s) uint32_t opmode = ret & 0xc0; if (opmode == 0x80) { - /* eeprom access */ - int eedo = prom9346_get_wire(s); - if (eedo) { + if (nmc93cxx_eeprom_read(s->eeprom)) ret |= 0x01; - } else { + else ret &= ~0x01; - } } rtl8139_log("Cfg9346 read val=0x%02x\n", ret); @@ -3120,70 +2901,103 @@ rtl8139_io_readl(uint32_t addr, void *priv) static uint32_t rtl8139_io_readl_ioport(uint16_t addr, void *priv) { - return rtl8139_io_readl(addr, priv); + uint32_t ret = 0xffffffff; + + ret = rtl8139_io_readl(addr, priv); + + rtl8139_log("[%04X:%08X] [RLI] %04X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static uint16_t rtl8139_io_readw_ioport(uint16_t addr, void *priv) { - return rtl8139_io_readw(addr, priv); + uint16_t ret = 0xffff; + + ret = rtl8139_io_readw(addr, priv); + + rtl8139_log("[%04X:%08X] [RWI] %04X = %04X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static uint8_t rtl8139_io_readb_ioport(uint16_t addr, void *priv) { - return rtl8139_io_readb(addr, priv); + uint8_t ret = 0xff; + + ret = rtl8139_io_readb(addr, priv); + + rtl8139_log("[%04X:%08X] [RBI] %04X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static void rtl8139_io_writel_ioport(uint16_t addr, uint32_t val, void *priv) { - return rtl8139_io_writel(addr, val, priv); + rtl8139_log("[%04X:%08X] [WLI] %04X = %08X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writel(addr, val, priv); } static void rtl8139_io_writew_ioport(uint16_t addr, uint16_t val, void *priv) { - return rtl8139_io_writew(addr, val, priv); + rtl8139_log("[%04X:%08X] [WWI] %04X = %04X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writew(addr, val, priv); } static void rtl8139_io_writeb_ioport(uint16_t addr, uint8_t val, void *priv) { - return rtl8139_io_writeb(addr, val, priv); + rtl8139_log("[%04X:%08X] [WBI] %04X = %02X\n", CS, cpu_state.pc, addr, val); + + rtl8139_io_writeb(addr, val, priv); } static uint32_t rtl8139_io_readl_mem(uint32_t addr, void *priv) { RTL8139State *s = (RTL8139State *) priv; + uint32_t ret = 0xffffffff; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return 0xffffffff; + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readl(addr, priv); - return rtl8139_io_readl(addr, priv); -} + rtl8139_log("[%04X:%08X] [RLM] %08X = %08X\n", CS, cpu_state.pc, addr, ret); + + return ret; + } static uint16_t rtl8139_io_readw_mem(uint32_t addr, void *priv) { RTL8139State *s = (RTL8139State *) priv; + uint16_t ret = 0xffff; + + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readw(addr, priv); - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return 0xffff; + rtl8139_log("[%04X:%08X] [RWM] %08X = %04X\n", CS, cpu_state.pc, addr, ret); - return rtl8139_io_readw(addr, priv); + return ret; } static uint8_t rtl8139_io_readb_mem(uint32_t addr, void *priv) { RTL8139State *s = (RTL8139State *) priv; + uint8_t ret = 0xff; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return 0xff; + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readb(addr, priv); - return rtl8139_io_readb(addr, priv); + rtl8139_log("[%04X:%08X] [RBM] %08X = %02X\n", CS, cpu_state.pc, addr, ret); + + return ret; } static void @@ -3191,10 +3005,10 @@ rtl8139_io_writel_mem(uint32_t addr, uint32_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return; + rtl8139_log("[%04X:%08X] [WLM] %08X = %08X\n", CS, cpu_state.pc, addr, val); - return rtl8139_io_writel(addr, val, priv); + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writel(addr, val, priv); } static void @@ -3202,10 +3016,10 @@ rtl8139_io_writew_mem(uint32_t addr, uint16_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return; + rtl8139_log("[%04X:%08X] [WWM] %08X = %04X\n", CS, cpu_state.pc, addr, val); - return rtl8139_io_writew(addr, val, priv); + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writew(addr, val, priv); } static void @@ -3213,10 +3027,10 @@ rtl8139_io_writeb_mem(uint32_t addr, uint8_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; - if ((addr < s->mem_base) || (addr > (s->mem_base + 0xff))) - return; + rtl8139_log("[%04X:%08X] [WBM] %08X = %02X\n", CS, cpu_state.pc, addr, val); - return rtl8139_io_writeb(addr, val, priv); + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + rtl8139_io_writeb(addr, val, priv); } static int @@ -3343,6 +3157,7 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) rtl8139_io_writeb_ioport, rtl8139_io_writew_ioport, rtl8139_io_writel_ioport, priv); s->pci_conf[addr & 0xFF] = val; + rtl8139_log("New I/O base: %04X\n", s->pci_conf[0x11] << 8); if (s->pci_conf[0x4] & PCI_COMMAND_IO) io_sethandler((s->pci_conf[0x11] << 8), 256, rtl8139_io_readb_ioport, rtl8139_io_readw_ioport, rtl8139_io_readl_ioport, @@ -3355,6 +3170,7 @@ rtl8139_pci_write(int func, int addr, uint8_t val, void *priv) case 0x17: s->pci_conf[addr & 0xFF] = val; s->mem_base = (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24); + rtl8139_log("New memory base: %08X\n", s->mem_base); if (s->pci_conf[0x4] & PCI_COMMAND_MEM) mem_mapping_set_addr(&s->bar_mem, (s->pci_conf[0x15] << 8) | (s->pci_conf[0x16] << 16) | (s->pci_conf[0x17] << 24), 256); break; @@ -3368,10 +3184,12 @@ static void * nic_init(const device_t *info) { RTL8139State *s = calloc(1, sizeof(RTL8139State)); - FILE *fp = NULL; + nmc93cxx_eeprom_params_t params; char eeprom_filename[1024] = { 0 }; - uint8_t *mac_bytes; - uint32_t mac; + char filename[1024] = { 0 }; + uint8_t *mac_bytes; + uint16_t *eep_data; + uint32_t mac; mem_mapping_add(&s->bar_mem, 0, 0, rtl8139_io_readb_mem, rtl8139_io_readw_mem, rtl8139_io_readl_mem, @@ -3382,31 +3200,26 @@ nic_init(const device_t *info) snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_rtl8139c_plus_%d.nvr", s->inst); - fp = nvr_fopen(eeprom_filename, "rb"); - if (fp) { - (void) !fread(s->eeprom.contents, 2, 64, fp); - fclose(fp); - fp = NULL; - } else { - /* prepare eeprom */ - s->eeprom.contents[0] = 0x8129; + eep_data = (uint16_t *) s->eeprom_data; + + /* prepare eeprom */ + eep_data[0] = 0x8129; - /* PCI vendor and device ID should be mirrored here */ - s->eeprom.contents[1] = 0x10EC; - s->eeprom.contents[2] = 0x8139; + /* PCI vendor and device ID should be mirrored here */ + eep_data[1] = 0x10EC; + eep_data[2] = 0x8139; - /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ + /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ #ifdef USE_REALTEK_OID - s->eeprom.contents[7] = 0xe000; - s->eeprom.contents[8] = 0x124c; + eep_data[7] = 0xe000; + eep_data[8] = 0x124c; #else - s->eeprom.contents[7] = 0x1400; - s->eeprom.contents[8] = 0x122a; + eep_data[7] = 0x1400; + eep_data[8] = 0x122a; #endif - s->eeprom.contents[9] = 0x1413; - } + eep_data[9] = 0x1413; - mac_bytes = (uint8_t *) &(s->eeprom.contents[7]); + mac_bytes = (uint8_t *) &(eep_data[7]); /* See if we have a local MAC address configured. */ mac = device_get_config_mac("mac", -1); @@ -3430,7 +3243,17 @@ nic_init(const device_t *info) for (uint32_t i = 0; i < 6; i++) s->phys[MAC0 + i] = mac_bytes[i]; - s->nic = network_attach(s, (uint8_t *) &s->eeprom.contents[7], rtl8139_do_receive, rtl8139_set_link_status); + params.nwords = 64; + params.default_content = (uint16_t *) s->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, device_get_instance()); + s->eeprom = device_add_parameters(&nmc93cxx_device, ¶ms); + if (!s->eeprom) { + free(s); + return NULL; + } + + s->nic = network_attach(s, (uint8_t *) &s->phys[MAC0], rtl8139_do_receive, rtl8139_set_link_status); timer_add(&s->timer, rtl8139_timer, s, 0); timer_on_auto(&s->timer, 1000000.0 / cpu_pci_speed); @@ -3444,17 +3267,6 @@ nic_init(const device_t *info) static void nic_close(void *priv) { - const RTL8139State *s = (RTL8139State *) priv; - FILE *fp = NULL; - char eeprom_filename[1024] = { 0 }; - - snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_rtl8139c_plus_%d.nvr", s->inst); - fp = nvr_fopen(eeprom_filename, "wb"); - if (fp) { - fwrite(s->eeprom.contents, 2, 64, fp); - fclose(fp); - fp = NULL; - } free(priv); } From 765a1f524ba4352c3b251b1ef84e63e0889b58ee Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 21 Dec 2023 02:03:27 +0600 Subject: [PATCH 047/146] Fix M3D programs --- src/video/vid_mga.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d0ec17bffae..498f2ff9cd1 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2686,7 +2686,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; break; @@ -2699,7 +2699,7 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; break; @@ -2739,7 +2739,7 @@ run_dma(mystique_t *mystique) if (mystique->dma.state == DMA_STATE_SEC) { mystique->dma.sec_state = 0; } - else if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; } @@ -2753,8 +2753,8 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.pri_state = 0; @@ -2772,8 +2772,8 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.pri_state = 0; @@ -2806,8 +2806,8 @@ run_dma(mystique_t *mystique) mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.pri_state = 0; @@ -2823,8 +2823,8 @@ run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { uint32_t val; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.words_expected = 0; @@ -2843,8 +2843,8 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) >= (mystique->dma.primend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; mystique->dma.words_expected = 0; @@ -2877,13 +2877,13 @@ fifo_thread(void *priv) mystique_t *mystique = (mystique_t *) priv; while (mystique->thread_run) { - int words_transferred = 0; thread_set_event(mystique->fifo_not_full_event); thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { - words_transferred = 0; + int words_transferred = 0; + while (!FIFO_EMPTY && words_transferred < 100) { fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; @@ -2910,13 +2910,13 @@ fifo_thread(void *priv) words_transferred++; } - } - /*Only run DMA once the FIFO is empty. Required by - Screamer 2 / Rally which will incorrectly clip an ILOAD - if DMA runs ahead*/ - if (!words_transferred) - run_dma(mystique); + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); + } } } @@ -2981,7 +2981,7 @@ mystique_softrap_pending_timer(void *priv) } /* Force ENDPRDMASTS flag to be set. */ if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS)) - wake_fifo_thread(mystique); + mystique->status |= STATUS_ENDPRDMASTS; } static void From 2d6ffe081e7c9f161e7414179bbaada40ef7f057 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 21 Dec 2023 14:40:32 +0600 Subject: [PATCH 048/146] Matrox Mystique: Force window resizing --- src/video/vid_mga.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 498f2ff9cd1..de6b1594f85 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -717,10 +717,12 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) mystique->crtcext_idx = val; break; case 0x3df: - if (mystique->crtcext_idx < 6) - mystique->crtcext_regs[mystique->crtcext_idx] = val; if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); + if (mystique->crtcext_idx < 6) { + mystique->crtcext_regs[mystique->crtcext_idx] = val; + svga_recalctimings(&mystique->svga); + } if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -952,6 +954,8 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); + reset_screen_size(); + video_force_resize_set_monitor(1, svga->monitor_index); #if 0 pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); #endif From 082337a381ff70441771b9c59372d9866177ce31 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 21 Dec 2023 13:36:46 +0100 Subject: [PATCH 049/146] Don't call svga_recalctimings() on MGA's port 0x3df, fixes Debian Woody's matroxfb screen test. --- src/video/vid_mga.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index de6b1594f85..8ee6e189737 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -719,10 +719,9 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) case 0x3df: if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); - if (mystique->crtcext_idx < 6) { + if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - svga_recalctimings(&mystique->svga); - } + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ From 011d4b50ec33a8b790af93c42d3a33c4330e23bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Dec 2023 15:05:15 +0100 Subject: [PATCH 050/146] Minor pause changes. --- src/86box.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/86box.c b/src/86box.c index 25b073fda92..33914d01731 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1581,10 +1581,10 @@ do_pause(int p) { int old_p = dopause; - if (p && !old_p) + if ((p == 1) && !old_p) do_pause_ack = p; - dopause = p; - if (p && !old_p) { + dopause = !!p; + if ((p == 1) && !old_p) { while (!atomic_load(&pause_ack)) ; } From 72cb0bedd044ba3ff6b27d6eaff2bdc3fc7aa9bd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Dec 2023 15:06:04 +0100 Subject: [PATCH 051/146] And QT. --- src/qt/qt_platform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index f306b613801..7ea28a4ced5 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -371,7 +371,7 @@ plat_pause(int p) wchar_t title[1024]; wchar_t paused_msg[512]; - if (p == dopause) { + if ((!!p) == dopause) { #ifdef Q_OS_WINDOWS if (source_hwnd) PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); From e469861d2b0d58d315eacf3a78d8544bfc5ccf2d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 21 Dec 2023 15:06:56 +0100 Subject: [PATCH 052/146] And finally, ACPI. --- src/acpi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/acpi.c b/src/acpi.c index 5672fb13535..9521d53373f 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -723,7 +723,8 @@ acpi_reg_write_common_regs(UNUSED(int size), uint16_t addr, uint8_t val, void *p /* Since the UI doesn't have a power button at the moment, pause emulation, then trigger a resume event so that the system resumes after unpausing. */ - plat_pause(1); + plat_pause(2); /* 2 means do not wait for pause as + we're already in the CPU thread. */ timer_set_delay_u64(&dev->resume_timer, 50 * TIMER_USEC); } } From 9ca9abebf482b56346f0f02eaaea055ded3e8018 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 22 Dec 2023 14:01:26 +0600 Subject: [PATCH 053/146] MGA: Don't reset screen size every recalctimings Fixes intense resizing. --- src/video/vid_mga.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8ee6e189737..675abd474ac 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -953,7 +953,6 @@ mystique_recalctimings(svga_t *svga) svga->fb_only = svga->packed_chain4; svga->disable_blink = (svga->bpp > 4); - reset_screen_size(); video_force_resize_set_monitor(1, svga->monitor_index); #if 0 pclog("PackedChain4=%d, chain4=%x, fast=%x, bit6 attrreg10=%02x, bits 5-6 gdcreg5=%02x, extmode=%02x.\n", svga->packed_chain4, svga->chain4, svga->fast, svga->attrregs[0x10] & 0x40, svga->gdcreg[5] & 0x60, mystique->pci_regs[0x41] & 1, mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE); From 6b7cb3a0d42588bd8ce7715f1daf4e5de2e867b6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 22 Dec 2023 15:14:53 +0600 Subject: [PATCH 054/146] mystique_line_compare: Return 1 Reduces glitches on M3D, although it doesn't eliminate it completely --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8ee6e189737..07b0edfe87a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -805,7 +805,7 @@ mystique_line_compare(svga_t *svga) mystique->status |= STATUS_VLINEPEN; mystique_update_irqs(mystique); - return 0; + return 1; } static void From 816bc6f5598443b6d0220cf5818b3032ec5e5d70 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 11:45:46 +0100 Subject: [PATCH 055/146] Mystique: Only update maback, the change will take place at the next retrace. --- src/video/vid_mga.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 3d6d28bd054..afd075035e6 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -886,6 +886,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ +#ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); @@ -893,6 +894,17 @@ mystique_recalctimings(svga_t *svga) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } +#else + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } +#endif svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { From bf52c1172b1441a3e72568b8c6d7288ae5670907 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Dec 2023 19:29:42 +0100 Subject: [PATCH 056/146] EGA: Implement PEL panning per hardware features. --- src/video/vid_ega.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index da77449b0b5..7cd6c6f174c 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -108,6 +108,8 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega_recalctimings(ega); } } else { + if ((ega->attraddr == 0x13) && (ega->attrregs[0x13] != val)) + ega->fullchange = changeframecount; o = ega->attrregs[ega->attraddr & 31]; ega->attrregs[ega->attraddr & 31] = val; if (ega->attraddr < 16) From 524fd30c0c2d1d7e044562ee14e15b8132fa0cb9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 22 Dec 2023 19:43:51 +0100 Subject: [PATCH 057/146] ATI Mach8/32 fixes regarding 1992 ATI Ultra drivers for Windows 3.1x: 1. For some reason, background colors were always black under those drivers in 8bpp mode, added a tweak to fix it (as well as Clock colors). 2. Likewise for the red scrolling in pbrush or write, added a tweak to its bitblt read mask. 3. Don't call svga_recalctimings in the hdisp/vdisp ports directly, fixes screen size on said drivers without affecting other stuff. --- src/video/vid_8514a.c | 8 +++++--- src/video/vid_ati_mach8.c | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 7e476663c3b..469a4555ea6 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -2940,9 +2940,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } else { while (count-- && dev->accel.sy >= 0) { if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + switch (frgd_mix) { case 0: src_dat = bkgd_color; + if (!bkgd_mix && (dev->accel.cmd & 0x40) && ((dev->accel.frgd_mix & 0x1f) == 7) && ((dev->accel.bkgd_mix & 0x1f) == 3) && !dev->bpp && (bkgd_color == 0x00)) /*For some reason, the September 1992 Mach8/32 drivers for Win3.x don't set the background colors properly.*/ + src_dat = frgd_color; break; case 1: src_dat = frgd_color; @@ -2962,7 +2964,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); + MIX(1, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } @@ -3740,7 +3742,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 3: READ(dev->accel.src + dev->accel.cx, src_dat); if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { + if ((dev->accel.cmd & 0x10) && !(dev->accel.cmd & 0x40)) { src_dat = ((src_dat & rd_mask) == rd_mask); } } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 89abde97775..5b8dedfbea7 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -3628,7 +3628,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x6e8: case 0x6e9: if (!(port & 1)) { - dev->hdisp = val; + if (!dev->on[0] || !dev->on[1]) + dev->hdisp = val; + mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); } svga_recalctimings(svga); @@ -3653,8 +3655,10 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x16e8: case 0x16e9: - WRITE8(port, dev->vdisp, val); - dev->vdisp &= 0x1fff; + if (!dev->on[0] || !dev->on[1]) { + WRITE8(port, dev->vdisp, val); + dev->vdisp &= 0x1fff; + } svga_recalctimings(svga); break; From ad6ddfb31e157eb979a32157785a61abb6457fb3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 23:11:24 +0100 Subject: [PATCH 058/146] Mystique and Millennium: Revert the ma change. --- src/video/vid_mga.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index afd075035e6..3d6d28bd054 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -886,7 +886,6 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ -#ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); @@ -894,17 +893,6 @@ mystique_recalctimings(svga_t *svga) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } -#else - /* Only change maback so the new display start will take effect on the next - horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } -#endif svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { From ede2ce91028a78641769303c38a21efc3ef566d9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 23:12:25 +0100 Subject: [PATCH 059/146] And reverted it again. --- src/video/vid_mga.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 3d6d28bd054..afd075035e6 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -886,6 +886,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ +#ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); @@ -893,6 +894,17 @@ mystique_recalctimings(svga_t *svga) svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); mystique->ma_latch_old = svga->ma_latch; } +#else + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } +#endif svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { From 539f9a06a57e45b019c23f960bdca94ac42ca11a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 22 Dec 2023 23:21:57 +0100 Subject: [PATCH 060/146] Mystique: Disable line compare, turns out it was disabled for a reason. --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index afd075035e6..eb3a28fc9e3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -805,7 +805,7 @@ mystique_line_compare(svga_t *svga) mystique->status |= STATUS_VLINEPEN; mystique_update_irqs(mystique); - return 1; + return 0; } static void From 7bba9cee78894aab4497cc4c7243fb311ddc9737 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 23 Dec 2023 14:03:18 +0600 Subject: [PATCH 061/146] Matrox Mystique: Fix display flickering issues for real Direct3D tests under Windows 95 do not flicker anymore, and the MSICUBE sample program renders correctly. --- src/video/vid_mga.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index eb3a28fc9e3..7e077209af3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -722,6 +722,28 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; + if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) + { + svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + if (mystique->type >= MGA_1064SG) + svga->rowoffset <<= 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + if (mystique->type >= MGA_1064SG) { + svga->ma_latch <<= 1; + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + } + } + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -886,6 +908,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ + svga->ma_latch <<= 1; #ifdef CHANGE_MA if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) @@ -2767,7 +2790,7 @@ run_dma(mystique_t *mystique) case DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2786,7 +2809,7 @@ run_dma(mystique_t *mystique) words_transferred++; } - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2820,7 +2843,7 @@ run_dma(mystique_t *mystique) mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2837,7 +2860,7 @@ run_dma(mystique_t *mystique) case DMA_MODE_BLIT: { uint32_t val; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; @@ -2857,7 +2880,7 @@ run_dma(mystique_t *mystique) blit_iload_write(mystique, val, 32); words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; mystique->dma.state = DMA_STATE_IDLE; From 94dfb353c0f5291f2f25abf8c53a2f8abd66c3dc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 23 Dec 2023 14:21:50 +0600 Subject: [PATCH 062/146] Fix NASCAR Racing 1994 regression --- src/video/vid_mga.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7e077209af3..b69a6506386 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -725,8 +725,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - if (mystique->type >= MGA_1064SG) - svga->rowoffset <<= 1; + svga->rowoffset <<= 1; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; From 28775d2583af3b7bb6eba2b04ce1f3cc1ee846f6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Dec 2023 14:11:46 +0100 Subject: [PATCH 063/146] Millennium: Do not ignore the interlace bit. --- src/video/vid_mga.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index b69a6506386..2720bea6858 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -887,9 +887,10 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) svga->split |= 0x400; - if (mystique->type == MGA_2064W) + if (mystique->type == MGA_2064W) { tvp3026_recalctimings(svga->ramdac, svga); - else + svga->interlace |= !!(mystique->crtcext_regs[0] & 0x80); + } else svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { From 012527fc4e31f1970fca83dfc0d6687f03b2cd99 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 23 Dec 2023 15:02:15 +0100 Subject: [PATCH 064/146] MGA flicker fixes. It's time to end the flickers once and for all by making the start address correctly emulated in vblank_start when in power graphics mode. --- src/video/vid_mga.c | 81 ++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2720bea6858..98e45fd2fed 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -722,27 +722,6 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 0 && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) - { - svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->rowoffset <<= 1; - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - if (mystique->type >= MGA_1064SG) { - svga->ma_latch <<= 1; - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } - } - } - if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ @@ -829,6 +808,33 @@ mystique_line_compare(svga_t *svga) return 0; } +static void +mystique_vblank_start(svga_t *svga) +{ + mystique_t *mystique = (mystique_t *) svga->priv; + + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) + svga->ma_latch <<= 1; + + if (mystique->type >= MGA_1064SG) { + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + svga->ma_latch <<= 1; + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + } + } +} + static void mystique_vsync_callback(svga_t *svga) { @@ -896,39 +902,14 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { svga->lowres = 0; svga->char_width = 8; - svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take - effect mid-screen*/ - svga->ma_latch <<= 1; -#ifdef CHANGE_MA - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } -#else - /* Only change maback so the new display start will take effect on the next - horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } -#endif - svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: @@ -979,9 +960,11 @@ mystique_recalctimings(svga_t *svga) } svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; + svga->vblank_start = mystique_vblank_start; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; + svga->vblank_start = NULL; if (mystique->type >= MGA_1064SG) svga->bpp = 8; } From 708a700abde20c8e438db4acb23ec1e5f5d68eba Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 23 Dec 2023 15:27:08 +0100 Subject: [PATCH 065/146] Mystique: Made the changes apply only to the Millennium. --- src/video/vid_mga.c | 67 ++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 98e45fd2fed..45ecd012f2e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -722,7 +722,31 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 4) { + if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { + svga->rowoffset = svga->crtc[0x13] | + ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->rowoffset <<= 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | + (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + + svga->ma_latch <<= 1; + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + } + + if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ svga->read_bank = (val & 0x7f) << 16; @@ -817,21 +841,6 @@ mystique_vblank_start(svga_t *svga) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) svga->ma_latch <<= 1; - - if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take - effect mid-screen*/ - svga->ma_latch <<= 1; - /* Only change maback so the new display start will take effect on the next - horizontal retrace. */ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } - } } } @@ -906,10 +915,28 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; + if (mystique->type >= MGA_1064SG) + svga->ma_latch <<= 1; + } if (mystique->type >= MGA_1064SG) { + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + svga->ma_latch <<= 1; + /* Only change maback so the new display start will take effect on the next + horizontal retrace. */ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } + svga->rowoffset <<= 1; switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { case XMULCTRL_DEPTH_8: @@ -960,13 +987,15 @@ mystique_recalctimings(svga_t *svga) } svga->packed_chain4 = 1; svga->line_compare = mystique_line_compare; - svga->vblank_start = mystique_vblank_start; + if (mystique->type < MGA_1064SG) + svga->vblank_start = mystique_vblank_start; } else { svga->packed_chain4 = 0; svga->line_compare = NULL; - svga->vblank_start = NULL; if (mystique->type >= MGA_1064SG) svga->bpp = 8; + else + svga->vblank_start = NULL; } svga->fb_only = svga->packed_chain4; From 933f402cc9aad4e41da5f1060dd6b19caea573c0 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 23 Dec 2023 13:27:25 -0500 Subject: [PATCH 066/146] Un-dev matrox mystique --- CMakeLists.txt | 1 - src/include/86box/video.h | 2 -- src/video/CMakeLists.txt | 4 ---- src/video/vid_mga.c | 2 -- src/video/vid_table.c | 2 -- src/win/Makefile.mingw | 10 ---------- 6 files changed, 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9f92add314..4bc020f15b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(LASERXT "VTech Laser XT" ON "DEV_BRANCH" OFF) -cmake_dependent_option(MGA "Matrox Mystique graphics adapters" ON "DEV_BRANCH" OFF) cmake_dependent_option(OLIVETTI "Olivetti M290" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPEN_AT "OpenAT" ON "DEV_BRANCH" OFF) cmake_dependent_option(PAS16 "Pro Audio Spectrum 16" ON "DEV_BRANCH" OFF) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 396b391241d..921b8e7785c 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -433,10 +433,8 @@ extern const device_t pgc_device; /* Matrox MGA */ extern const device_t millennium_device; -# if defined(DEV_BRANCH) && defined(USE_MGA) extern const device_t mystique_device; extern const device_t mystique_220_device; -# endif /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 6635252a6d6..638837757ae 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -28,10 +28,6 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_ibm_rgb528_ramdac.c vid_sdac_ramdac.c vid_ogc.c vid_mga.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c vid_xga.c) -if(MGA) - target_compile_definitions(vid PRIVATE USE_MGA) -endif() - if(VGAWONDER) target_compile_definitions(vid PRIVATE USE_VGAWONDER) endif() diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 45ecd012f2e..4a4d9169e7a 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5945,7 +5945,6 @@ const device_t millennium_device = { .config = mystique_config }; -#if defined(DEV_BRANCH) && defined(USE_MGA) const device_t mystique_device = { .name = "Matrox Mystique", .internal_name = "mystique", @@ -5973,4 +5972,3 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; -#endif diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 0131fa3a442..ad6fca2c67d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -205,10 +205,8 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, -#if defined(DEV_BRANCH) && defined(USE_MGA) { &mystique_device }, { &mystique_220_device }, -#endif { &tgui9440_pci_device }, { &tgui9660_pci_device }, { &tgui9680_pci_device }, diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 13dbdcefedb..8e4b99b56fc 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -64,9 +64,6 @@ ifeq ($(DEV_BUILD), y) ifndef LASERXT LASERXT := y endif - ifndef MGA - MGA := y - endif ifndef OLIVETTI OLIVETTI := y endif @@ -128,9 +125,6 @@ else ifndef LASERXT LASERXT := n endif - ifndef MGA - MGA := n - endif ifndef OLIVETTI OLIVETTI := n endif @@ -496,10 +490,6 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += m_xt_laserxt.o endif - ifeq ($(MGA), y) - OPTS += -DUSE_MGA - endif - ifeq ($(OPEN_AT), y) OPTS += -DUSE_OPEN_AT endif From 70d6d5954bd65dd7123c9d2f0fd6c7a302f37396 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 01:46:10 +0600 Subject: [PATCH 067/146] MGA: Implement gamma correction for 24+ bpp modes --- src/include/86box/vid_svga.h | 3 ++ src/include/86box/video.h | 3 ++ src/video/vid_mga.c | 2 + src/video/vid_svga_render.c | 80 +++++++++++++++++++++--------------- 4 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 682a66111b1..52a9c9b0acc 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -268,6 +268,9 @@ typedef struct svga_t { /* Pointer to monitor */ monitor_t *monitor; + /* Enable LUT mapping of >= 24 bpp modes. */ + int lut_map; + void * dev8514; void * xga; } svga_t; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 396b391241d..4d8302982bc 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -32,6 +32,9 @@ using atomic_int = std::atomic_int; #define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) #define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) +#define getcolr(color) (((color) >> 16) & 0xFF) +#define getcolg(color) (((color) >> 8) & 0xFF) +#define getcolb(color) ((color) & 0xFF) enum { VID_NONE = 0, diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 45ecd012f2e..1f93c339e66 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -914,6 +914,7 @@ mystique_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->lut_map = 1; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; @@ -992,6 +993,7 @@ mystique_recalctimings(svga_t *svga) } else { svga->packed_chain4 = 0; svga->line_compare = NULL; + svga->lut_map = 0; if (mystique->type >= MGA_1064SG) svga->bpp = 8; else diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 7a15dc1cfe6..e94916fd5e0 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -30,6 +30,20 @@ #include <86box/vid_svga_render.h> #include <86box/vid_svga_render_remap.h> +static inline uint32_t +lookup_lut_ram(svga_t* svga, uint32_t val) +{ + if (!svga->lut_map) + return val; + + uint8_t r = getcolr(svga->pallook[getcolr(val)]); + uint8_t g = getcolg(svga->pallook[getcolg(val)]); + uint8_t b = getcolb(svga->pallook[getcolb(val)]); + return makecol32(r, g, b) | (val & 0xFF000000); +} + +#define lookup_lut(val) lookup_lut_ram(svga, val) + void svga_render_null(svga_t *svga) { @@ -1422,7 +1436,7 @@ svga_render_24bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; svga->ma &= svga->vram_display_mask; - svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; + svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(fg); } } } else { @@ -1441,10 +1455,10 @@ svga_render_24bpp_lowres(svga_t *svga) dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = lookup_lut(dat0 & 0xffffff); + p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + p[6] = p[7] = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1457,10 +1471,10 @@ svga_render_24bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = lookup_lut(dat0 & 0xffffff); + p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + p[6] = p[7] = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1495,16 +1509,16 @@ svga_render_24bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + p[x] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; + p[x + 1] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; + p[x + 2] = lookup_lut(dat & 0xffffff); dat = *(uint32_t *) (&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; + p[x + 3] = lookup_lut(dat & 0xffffff); svga->ma += 12; } @@ -1526,10 +1540,10 @@ svga_render_24bpp_highres(svga_t *svga) dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = lookup_lut(dat0 & 0xffffff); + *p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + *p++ = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1542,10 +1556,10 @@ svga_render_24bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma + 8); dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = lookup_lut(dat0 & 0xffffff); + *p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8)); + *p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16)); + *p++ = lookup_lut(dat2 >> 8); svga->ma += 12; } @@ -1577,7 +1591,7 @@ svga_render_32bpp_lowres(svga_t *svga) dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; svga->ma &= svga->vram_display_mask; - svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; + svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(dat); } } } else { @@ -1593,16 +1607,16 @@ svga_render_32bpp_lowres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); + *p++ = lookup_lut(dat & 0xffffff); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); + *p++ = lookup_lut(dat & 0xffffff); svga->ma += 4; } svga->ma &= svga->vram_display_mask; @@ -1633,7 +1647,7 @@ svga_render_32bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + p[x] = lookup_lut(dat & 0xffffff); } svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -1651,14 +1665,14 @@ svga_render_32bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + *p++ = lookup_lut(dat & 0xffffff); svga->ma += 4; } @@ -1692,14 +1706,14 @@ svga_render_ABGR8888_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); } svga->ma += x * 4; } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + *p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); svga->ma += 4; } @@ -1732,14 +1746,14 @@ svga_render_RGBA8888_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat >> 8; + *p++ = lookup_lut(dat >> 8); } svga->ma += (x * 4); } else { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat >> 8; + *p++ = lookup_lut(dat >> 8); svga->ma += 4; } From 0a55e75b06fda425e493377d1487bd27905a770b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 02:16:51 +0600 Subject: [PATCH 068/146] MGA: Gamma-correct hardware cursor --- src/include/86box/vid_svga.h | 2 ++ src/video/vid_mga.c | 2 +- src/video/vid_svga_render.c | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 52a9c9b0acc..70964145778 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -337,6 +337,8 @@ enum { RAMDAC_8BIT }; +uint32_t svga_lookup_lut_ram(svga_t* svga, uint32_t val); + /* We need a way to add a device with a pointer to a parent device so it can attach itself to it, and possibly also a second ATi 68860 RAM DAC type that auto-sets SVGA render on RAM DAC render change. */ extern void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 1f93c339e66..a04187fbed3 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5404,7 +5404,7 @@ mystique_hwcursor_draw(svga_t *svga, int displine) case XCURCTRL_CURMODE_XGA: for (uint8_t x = 0; x < 64; x++) { if (!(dat[1] & (1ULL << 63))) - svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; + svga->monitor->target_buffer->line[displine][offset + svga->x_add] = (dat[0] & (1ULL << 63)) ? svga_lookup_lut_ram(svga, mystique->cursor.col[1]) : svga_lookup_lut_ram(svga, mystique->cursor.col[0]); else if (dat[0] & (1ULL << 63)) svga->monitor->target_buffer->line[displine][offset + svga->x_add] ^= 0xffffff; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index e94916fd5e0..18e0438fdd4 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -30,8 +30,8 @@ #include <86box/vid_svga_render.h> #include <86box/vid_svga_render_remap.h> -static inline uint32_t -lookup_lut_ram(svga_t* svga, uint32_t val) +uint32_t +svga_lookup_lut_ram(svga_t* svga, uint32_t val) { if (!svga->lut_map) return val; @@ -42,7 +42,7 @@ lookup_lut_ram(svga_t* svga, uint32_t val) return makecol32(r, g, b) | (val & 0xFF000000); } -#define lookup_lut(val) lookup_lut_ram(svga, val) +#define lookup_lut(val) svga_lookup_lut_ram(svga, val) void svga_render_null(svga_t *svga) From 7701caf2312da6602cf6d13c5d03ca2d8a212a4e Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 14:18:55 +0600 Subject: [PATCH 069/146] Mystique: Fix flickering display on Direct3D --- src/video/vid_mga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 74a81741bee..119d3ad15d9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -915,6 +915,7 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); svga->lut_map = 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; From 0eb2b2915e5541430b6ec7a34f67fbc0b8040d3a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 24 Dec 2023 14:22:23 +0600 Subject: [PATCH 070/146] Don't apply to Millennium --- src/video/vid_mga.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 119d3ad15d9..2eb129c0729 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -915,7 +915,8 @@ mystique_recalctimings(svga_t *svga) svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); svga->lut_map = 1; - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->type >= MGA_1064SG) + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { svga->rowoffset <<= 1; From c933b24f8b5853709196c9069cd8d0b9dc7bab14 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 24 Dec 2023 23:00:57 +0100 Subject: [PATCH 071/146] FDD: Return nothing on timeout, makes IBM PC and XT actually return Not ready instead of General failure when the drive is not ready. --- src/floppy/fdd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 09e791c4edf..ef489c44574 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -563,8 +563,10 @@ fdd_poll(void *priv) if (fdd_notfound) { fdd_notfound--; +#ifdef RETURN_NOIDAM if (!fdd_notfound) fdc_noidam(fdd_fdc); +#endif } } @@ -606,6 +608,8 @@ fdd_reset(void) void fdd_readsector(int drive, int sector, int track, int side, int density, int sector_size) { + pclog("readsector = %08X\n", drives[drive].readsector); + if (drives[drive].readsector) drives[drive].readsector(drive, sector, track, side, density, sector_size); else From db788c6580f0d2d2a36f608fdfa4a9f83268133c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 24 Dec 2023 23:01:55 +0100 Subject: [PATCH 072/146] Removed an excess logging line from floppy/fdd.c. --- src/floppy/fdd.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index ef489c44574..845a6f35ef6 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -608,8 +608,6 @@ fdd_reset(void) void fdd_readsector(int drive, int sector, int track, int side, int density, int sector_size) { - pclog("readsector = %08X\n", drives[drive].readsector); - if (drives[drive].readsector) drives[drive].readsector(drive, sector, track, side, density, sector_size); else From 278661c41c2a85725e3ee36ef28e1da9a7713180 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 25 Dec 2023 14:05:07 +0600 Subject: [PATCH 073/146] Mystique: Don't do busmastering until SOFTRAP status is read MSICUBE sample for Windows 9x no longer freezes the entire VM after a while --- src/video/vid_mga.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2eb129c0729..4bc0f97f955 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -440,7 +440,10 @@ typedef struct mystique_t { uint32_t vram_mask, vram_mask_w, vram_mask_l, lfb_base, ctrl_base, iload_base, ma_latch_old, maccess, mctlwtst, maccess_running, - status, softrap_pending_val; + softrap_pending_val; + + atomic_uint status; + atomic_bool softrap_status_read; uint64_t blitter_time, status_time; @@ -1483,13 +1486,16 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) ret = mystique->status & 0xff; if (svga->cgastat & 8) ret |= REG_STATUS_VSYNCSTS; + if (ret & 1) + mystique->softrap_status_read = 1; break; case REG_STATUS + 1: ret = (mystique->status >> 8) & 0xff; break; case REG_STATUS + 2: ret = (mystique->status >> 16) & 0xff; - if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY) + if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY + || mystique->dma.state != DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) ret |= (STATUS_DWGENGSTS >> 16); break; case REG_STATUS + 3: @@ -2724,6 +2730,12 @@ run_dma(mystique_t *mystique) thread_wait_mutex(mystique->dma.lock); + if (mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read) + { + thread_release_mutex(mystique->dma.lock); + return; + } + if (mystique->dma.state == DMA_STATE_IDLE) { if (!(mystique->status & STATUS_ENDPRDMASTS)) { @@ -3025,16 +3037,14 @@ mystique_softrap_pending_timer(void *priv) mystique->status |= STATUS_ENDPRDMASTS; } if (mystique->softrap_pending) { - mystique->softrap_pending--; - mystique->dma.secaddress = mystique->softrap_pending_val; mystique->status |= STATUS_SOFTRAPEN; + mystique->softrap_status_read = 0; //pclog("softrapen\n"); mystique_update_irqs(mystique); + mystique->softrap_pending--; } - /* Force ENDPRDMASTS flag to be set. */ - if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->status & STATUS_ENDPRDMASTS)) - mystique->status |= STATUS_ENDPRDMASTS; + } static void @@ -5838,6 +5848,8 @@ mystique_init(const device_t *info) timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1); mystique->status = STATUS_ENDPRDMASTS; + + mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; From 1bd4bbdfa1f7352b11f0b0f2b63ff8d9602b9d0a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 25 Dec 2023 15:24:52 +0600 Subject: [PATCH 074/146] MGA: Implement gamma-correction for <= 16 bpp modes --- src/include/86box/vid_svga.h | 3 + src/video/vid_mga.c | 26 +++++++ src/video/vid_svga.c | 7 ++ src/video/vid_svga_render.c | 136 +++++++++++++++++------------------ 4 files changed, 104 insertions(+), 68 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 70964145778..fc6c02c2070 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -271,6 +271,9 @@ typedef struct svga_t { /* Enable LUT mapping of >= 24 bpp modes. */ int lut_map; + /* Return a 32 bpp color from a 15/16 bpp color. */ + uint32_t (*conv_16to32)(struct svga_t *svga, uint16_t color, uint8_t bpp); + void * dev8514; void * xga; } svga_t; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 4bc0f97f955..f0cbad9eb37 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5728,6 +5728,31 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } } +static uint32_t +mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + mystique_t *mystique = (mystique_t*)svga->priv; + + if (svga->lut_map) { + if (bpp == 15) { + if (mystique->xgenctrl & (1 << 2)) { + color &= 0x7FFF; + } + uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); + uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); + uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); + return video_15to32[color] & 0xFF000000 | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[color & 0x1f]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); + return video_16to32[color] & 0xFF000000 | makecol(r, g, b); + } + } + + return (bpp == 15) ? video_15to32[color] : video_16to32[color]; +} + static void * mystique_init(const device_t *info) { @@ -5852,6 +5877,7 @@ mystique_init(const device_t *info) mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; + mystique->svga.conv_16to32 = mystique_conv_16to32; mystique->i2c = i2c_gpio_init("i2c_mga"); mystique->i2c_ddc = i2c_gpio_init("ddc_mga"); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 1479ea7181f..be53a01700a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1102,6 +1102,12 @@ svga_poll(void *priv) } } +uint32_t +svga_conv_16to32(struct svga_t *svga, uint16_t color, uint8_t bpp) +{ + return (bpp == 15) ? video_15to32[color] : video_16to32[color]; +} + int svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), @@ -1148,6 +1154,7 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, svga->video_out = video_out; svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; + svga->conv_16to32 = svga_conv_16to32; svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 18e0438fdd4..e3f4bff5e9d 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -1042,13 +1042,13 @@ svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; + p[x << 1] = p[(x << 1) + 1] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[(x << 1) + 2] = p[(x << 1) + 3] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[(x << 1) + 6] = p[(x << 1) + 7] = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1067,13 +1067,13 @@ svga_render_15bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; } else { @@ -1081,8 +1081,8 @@ svga_render_15bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); svga->ma += 4; } } @@ -1113,20 +1113,20 @@ svga_render_15bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + p[x] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 1] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + p[x + 2] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 3] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + p[x + 4] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 5] = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + p[x + 6] = svga->conv_16to32(svga, dat & 0xffff, 15); + p[x + 7] = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1144,20 +1144,20 @@ svga_render_15bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); } svga->ma += x << 1; } else { @@ -1165,8 +1165,8 @@ svga_render_15bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 15); + *p++ = svga->conv_16to32(svga, dat >> 16, 15); svga->ma += 4; } } @@ -1194,16 +1194,16 @@ svga_render_15bpp_mix_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x << 1] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1229,24 +1229,24 @@ svga_render_15bpp_mix_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); dat >>= 16; - p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : svga->conv_16to32(svga, dat & 0xffff, 15); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1275,12 +1275,12 @@ svga_render_16bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x << 1] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; + p[x << 1] = p[(x << 1) + 1] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[(x << 1) + 2] = p[(x << 1) + 3] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; + p[(x << 1) + 4] = p[(x << 1) + 5] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[(x << 1) + 6] = p[(x << 1) + 7] = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1299,13 +1299,13 @@ svga_render_16bpp_lowres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; } else { @@ -1313,8 +1313,8 @@ svga_render_16bpp_lowres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += 4; } @@ -1345,20 +1345,20 @@ svga_render_16bpp_highres(svga_t *svga) for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { uint32_t dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + p[x] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 1] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + p[x + 2] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 3] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + p[x + 4] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 5] = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + p[x + 6] = svga->conv_16to32(svga, dat & 0xffff, 16); + p[x + 7] = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; svga->ma &= svga->vram_display_mask; @@ -1376,20 +1376,20 @@ svga_render_16bpp_highres(svga_t *svga) if (!svga->remap_required) { for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); } svga->ma += x << 1; } else { @@ -1397,8 +1397,8 @@ svga_render_16bpp_highres(svga_t *svga) addr = svga->remap_func(svga, svga->ma); dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = svga->conv_16to32(svga, dat & 0xffff, 16); + *p++ = svga->conv_16to32(svga, dat >> 16, 16); svga->ma += 4; } From e812b3c3b1cd0db1a33d8fc0e5a0f5015b3adda0 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 07:05:02 +0500 Subject: [PATCH 075/146] ESC/P: Use the new dot matrix font Also remove the fallback to Courier as it's no longer needed --- src/include/86box/printer.h | 2 +- src/printer/prt_escp.c | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/include/86box/printer.h b/src/include/86box/printer.h index eb6eb4a753b..8efba343ef5 100644 --- a/src/include/86box/printer.h +++ b/src/include/86box/printer.h @@ -46,7 +46,7 @@ #ifndef PRINTER_H #define PRINTER_H -#define FONT_FILE_DOTMATRIX "dotmatrix.ttf" +#define FONT_FILE_DOTMATRIX "dotmatrix.otf" #define FONT_FILE_ROMAN "roman.ttf" #define FONT_FILE_SANSSERIF "sansserif.ttf" diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index c1147978681..cd02790784b 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -545,17 +545,6 @@ update_font(escp_t *dev) if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; - - /* Try to fall back to Courier in case the dot matrix font is absent. */ - if (!strcmp(fn, FONT_FILE_DOTMATRIX)) { - strcpy(path, dev->fontpath); - path_slash(path); - strcat(path, FONT_FILE_COURIER); - if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { - escp_log("ESC/P: unable to load font '%s'\n", path); - dev->fontface = NULL; - } - } } if (!dev->multipoint_mode) { From a9d96371dcbbf8872900230b9e43958508d4067e Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 07:06:39 +0500 Subject: [PATCH 076/146] ESC/P: Add workaround for glyphs with negative offsets Fixes characters disappearing when printed very close to the paper edges --- src/printer/prt_escp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index cd02790784b..6ae706cc8ad 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1578,8 +1578,8 @@ handle_char(escp_t *dev, uint8_t ch) FT_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); } - pen_x = PIXX + dev->fontface->glyph->bitmap_left; - pen_y = (uint16_t) (PIXY - dev->fontface->glyph->bitmap_top + dev->fontface->size->metrics.ascender / 64); + pen_x = PIXX + fmax(0.0, dev->fontface->glyph->bitmap_left); + pen_y = (uint16_t) (PIXY + fmax(0.0, -dev->fontface->glyph->bitmap_top + dev->fontface->size->metrics.ascender / 64)); if (dev->font_style & STYLE_SUBSCRIPT) pen_y += dev->fontface->glyph->bitmap.rows / 2; From aab48daff79d2a35c6246a5f954d5e22208834b3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Dec 2023 13:10:48 +0100 Subject: [PATCH 077/146] Fixed the two warnings in video/vid_mga.c. --- src/video/vid_mga.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f0cbad9eb37..19720f674be 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5732,25 +5732,26 @@ static uint32_t mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) { mystique_t *mystique = (mystique_t*)svga->priv; + uint32_t ret = 0x00000000; if (svga->lut_map) { if (bpp == 15) { - if (mystique->xgenctrl & (1 << 2)) { + if (mystique->xgenctrl & (1 << 2)) color &= 0x7FFF; - } uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); - return video_15to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); } else { uint8_t b = getcolr(svga->pallook[color & 0x1f]); uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); - return video_16to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); } - } - - return (bpp == 15) ? video_15to32[color] : video_16to32[color]; + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; } static void * From 7ff4fd355fd0426bb2dd9e67ff85bd5382d00167 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 17:33:43 +0500 Subject: [PATCH 078/146] ESC/P: Add handling for a separate italic dot matrix font --- src/include/86box/printer.h | 3 ++- src/printer/prt_escp.c | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/include/86box/printer.h b/src/include/86box/printer.h index 8efba343ef5..b576fbf27a8 100644 --- a/src/include/86box/printer.h +++ b/src/include/86box/printer.h @@ -46,7 +46,8 @@ #ifndef PRINTER_H #define PRINTER_H -#define FONT_FILE_DOTMATRIX "dotmatrix.otf" +#define FONT_FILE_DOTMATRIX "dotmatrix.otf" +#define FONT_FILE_DOTMATRIX_ITALIC "dotmatrix_italic.otf" #define FONT_FILE_ROMAN "roman.ttf" #define FONT_FILE_SANSSERIF "sansserif.ttf" diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 6ae706cc8ad..2349c67a152 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -508,9 +508,12 @@ update_font(escp_t *dev) if (dev->fontface) FT_Done_Face(dev->fontface); - if (dev->print_quality == QUALITY_DRAFT) - fn = FONT_FILE_DOTMATRIX; - else + if (dev->print_quality == QUALITY_DRAFT) { + if (dev->font_style & STYLE_ITALICS) + fn = FONT_FILE_DOTMATRIX_ITALIC; + else + fn = FONT_FILE_DOTMATRIX; + } else switch (dev->lq_typeface) { case TYPEFACE_ROMAN: fn = FONT_FILE_ROMAN; @@ -592,7 +595,7 @@ update_font(escp_t *dev) (uint16_t) (hpoints * 64), (uint16_t) (vpoints * 64), dev->dpi, dev->dpi); - if ((dev->font_style & STYLE_ITALICS) || (dev->char_tables[dev->curr_char_table] == 0)) { + if ((dev->print_quality != QUALITY_DRAFT) && ((dev->font_style & STYLE_ITALICS) || (dev->char_tables[dev->curr_char_table] == 0))) { /* Italics transformation. */ matrix.xx = 0x10000L; matrix.xy = (FT_Fixed) (0.20 * 0x10000L); From 8b4c93fdfe031fbb11c5bbf83d850dd105b5e3d1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov <2708460+lemondrops@users.noreply.github.com> Date: Mon, 25 Dec 2023 07:07:13 +0500 Subject: [PATCH 079/146] ESC/P: Set draft print quality by default --- src/printer/prt_escp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 2349c67a152..8247ecfab8f 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -437,6 +437,7 @@ reset_printer(escp_t *dev) dev->cpi = PAGE_CPI; dev->curr_char_table = 1; dev->font_style = 0; + dev->print_quality = QUALITY_DRAFT; dev->extra_intra_space = 0.0; dev->print_upper_control = 1; dev->bg_remaining_bytes = 0; From 7678a86d6c55f7549acd9884f24e8a6499b5ec7d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 02:21:48 +0100 Subject: [PATCH 080/146] MGA: LUT enable/disable and corrected 15bpp gamma correction. --- src/video/vid_mga.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 19720f674be..49d44c06d5e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -234,6 +234,7 @@ #define XREG_XPIXPLLSTAT 0x4f #define XMISCCTRL_VGA8DAC (1 << 3) +#define XMISCCTRL_RAMCS (1 << 4) #define XMULCTRL_DEPTH_MASK (7 << 0) #define XMULCTRL_DEPTH_8 (0 << 0) @@ -917,7 +918,7 @@ mystique_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->lut_map = 1; + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); if (mystique->type >= MGA_1064SG) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; @@ -1321,6 +1322,8 @@ mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) case XREG_XMISCCTRL: mystique->xmiscctrl = val; svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); break; case XREG_XGENCTRL: @@ -5738,15 +5741,21 @@ mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) if (bpp == 15) { if (mystique->xgenctrl & (1 << 2)) color &= 0x7FFF; +#if 0 uint8_t b = getcolr(svga->pallook[(color & 0x1F) | (!!(color & 0x8000) >> 8)]); uint8_t g = getcolg(svga->pallook[((color & 0x3E0) >> 5) | (!!(color & 0x8000) >> 8)]); uint8_t r = getcolb(svga->pallook[((color & 0x7C00) >> 10) | (!!(color & 0x8000) >> 8)]); - ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); +#else + uint8_t b = getcolr(svga->pallook[color & 0x1f]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 5]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 10]); +#endif + ret = video_15to32[color] & 0xFF000000 | makecol(r, g, b); } else { uint8_t b = getcolr(svga->pallook[color & 0x1f]); uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); - ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + ret = video_16to32[color] & 0xFF000000 | makecol(r, g, b); } } else ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; From f0f52279c45a917a7e5eaf93f1ff09ce047e40ff Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 02:48:55 +0100 Subject: [PATCH 081/146] Restore correct CGA compatible mode behavior in (S)VGA. --- src/video/vid_svga.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index be53a01700a..449c1b33ce5 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -618,7 +618,7 @@ svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 31; + svga->rowcount = svga->crtc[9] & 0x1f; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -639,27 +639,26 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; + } else if ((svga->gdcreg[5] & 0x60) == 0x20) { + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ + if (svga->lowres) /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; else svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { From c597a44c87587112bb755559da5400c24463bda1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 27 Dec 2023 14:44:58 +0600 Subject: [PATCH 082/146] Mystique: Make sure dxdiag on D3D 9.0b doesn't crash the emulator on Win98SE --- src/video/vid_mga.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 49d44c06d5e..2b5c92ed35d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2511,6 +2511,16 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } + /* HACK: For DirectX 9.0b Direct3D testing on Windows 98 SE. + + The 4.12.013 drivers give an out-of-bounds busmastering range when dxdiag enumerates Direct3D, with exactly 16384 bytes of difference. + Don't attempt busmastering in such cases. This isn't ideal, but there are no more crashes faced in this case. */ + if ((mystique->dma.primend & DMA_ADDR_MASK) < (mystique->dma.primaddress & DMA_ADDR_MASK) && ((mystique->dma.primaddress & DMA_ADDR_MASK) - (mystique->dma.primend & DMA_ADDR_MASK)) == 0x4000) + { + mystique->dma.primaddress = mystique->dma.primend; + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } thread_release_mutex(mystique->dma.lock); break; From d9a571c179611178dc5d2ed6142ad8f3b39a7a04 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:37:37 +0100 Subject: [PATCH 083/146] A small preparation in vid_svga. --- src/include/86box/vid_svga.h | 1 + src/video/vid_svga.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index fc6c02c2070..f55ec930cc6 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -231,6 +231,7 @@ typedef struct svga_t { uint8_t dac_status; uint8_t dpms; uint8_t dpms_ui; + uint8_t color_4bpp; uint8_t ksc5601_sbyte_mask; uint8_t ksc5601_udc_area_msb[2]; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index be53a01700a..ed93a6f3d99 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -174,8 +174,10 @@ svga_out(uint16_t addr, uint8_t val, void *priv) svga->fullchange = svga->monitor->mon_changeframecount; o = svga->attrregs[svga->attraddr & 31]; svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) + if (svga->attraddr < 16) { + svga->color_4bpp = (val >> 4) & 0x03; svga->fullchange = svga->monitor->mon_changeframecount; + } if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { for (int c = 0; c < 16; c++) { if (svga->attrregs[0x10] & 0x80) { From 2002f8e34e1d1a679d9495cd5f8a25cbe6293b94 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:38:43 +0100 Subject: [PATCH 084/146] Fixed the variable's name. --- src/include/86box/vid_svga.h | 2 +- src/video/vid_svga.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index f55ec930cc6..b44f101cbdf 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -231,7 +231,7 @@ typedef struct svga_t { uint8_t dac_status; uint8_t dpms; uint8_t dpms_ui; - uint8_t color_4bpp; + uint8_t color_2bpp; uint8_t ksc5601_sbyte_mask; uint8_t ksc5601_udc_area_msb[2]; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 94759ae5d61..c41624bf71a 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -175,7 +175,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) o = svga->attrregs[svga->attraddr & 31]; svga->attrregs[svga->attraddr & 31] = val; if (svga->attraddr < 16) { - svga->color_4bpp = (val >> 4) & 0x03; + svga->color_2bpp = (val >> 4) & 0x03; svga->fullchange = svga->monitor->mon_changeframecount; } if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { @@ -620,7 +620,7 @@ svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 0x1f; + svga->rowcount = svga->crtc[9] & 31; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -641,26 +641,27 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; - } else if ((svga->gdcreg[5] & 0x60) == 0x20) { - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->lowres) /*Low res (320)*/ + if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; else svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { From 35450fe632444f8b38d9edc0ae4c2447a2743843 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:47:42 +0100 Subject: [PATCH 085/146] Restored some previously reverted changes. --- src/video/vid_svga.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index c41624bf71a..9f125fb728b 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -620,7 +620,7 @@ svga_recalctimings(svga_t *svga) svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 31; + svga->rowcount = svga->crtc[9] & 0x1f; svga->hdisp_time = svga->hdisp; svga->render = svga_render_blank; @@ -641,27 +641,26 @@ svga_recalctimings(svga_t *svga) svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; svga->hdisp_old = svga->hdisp; - if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) == 0x00)) { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) { if ((svga->gdcreg[5] & 0x60) == 0x00) { if (svga->seqregs[1] & 8) /*Low res (320)*/ svga->render = svga_render_4bpp_lowres; else svga->render = svga_render_4bpp_highres; + } else if ((svga->gdcreg[5] & 0x60) == 0x20) { + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; } else { svga->map8 = svga->pallook; - if (svga->attrregs[0x10] & 0x40) /*Low res (320)*/ + if (svga->lowres) /*Low res (320)*/ svga->render = svga_render_8bpp_lowres; else svga->render = svga_render_8bpp_highres; } } else { switch (svga->gdcreg[5] & 0x60) { - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; case 0x40: case 0x60: /*256+ colours*/ switch (svga->bpp) { From c240db50ba58eb0862cb087301cfffd98c9a084a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 15:49:13 +0100 Subject: [PATCH 086/146] Restored some accidentally reverted parentheses. --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2b5c92ed35d..35354b2ad3d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5760,12 +5760,12 @@ mystique_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 10]); #endif - ret = video_15to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); } else { uint8_t b = getcolr(svga->pallook[color & 0x1f]); uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 5]); uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 11]); - ret = video_16to32[color] & 0xFF000000 | makecol(r, g, b); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); } } else ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; From 1798b2e51ca2fd201ba22b6f40f890f8d70bcaa1 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 16:07:03 +0100 Subject: [PATCH 087/146] ATI VGA mode fixes: 1. Fixed 4-bit packed modes. 2. Preparation of fixing the 2-bit modes. 3. Extra: fixed the accelerator mode switches again (Mach8/32 only). --- src/include/86box/vid_svga.h | 2 + src/video/vid_ati18800.c | 22 +++++++-- src/video/vid_ati28800.c | 93 ++++++++++++------------------------ src/video/vid_ati_mach8.c | 42 +++++++++++----- 4 files changed, 83 insertions(+), 76 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index b44f101cbdf..3e7c6f3fe22 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -128,6 +128,8 @@ typedef struct svga_t { int hblank_sub; int hblank_end_val; int hblank_end_len; + int packed_4bpp; + int ati_4color; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 09e813babf4..b54f6b89eeb 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -186,8 +186,22 @@ ati18800_recalctimings(svga_t *svga) svga->gdcreg[5] &= ~0x40; } - if (ati18800->regs[0xb0] & 6) + if (ati18800->regs[0xb0] & 6) { svga->gdcreg[5] |= 0x40; + if ((ati18800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((ati18800->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { @@ -215,8 +229,10 @@ ati18800_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; } diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index aa5800d1cd2..09d6279f422 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -400,7 +400,10 @@ ati28800k_in(uint16_t addr, void *priv) static void ati28800_recalctimings(svga_t *svga) { - const ati28800_t *ati28800 = (ati28800_t *) svga->priv; + ati28800_t *ati28800 = (ati28800_t *) svga->priv; + int clock_sel; + + clock_sel = ((svga->miscout >> 2) & 3) | ((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1); if (ati28800->regs[0xa3] & 0x10) svga->ma_latch |= 0x10000; @@ -408,66 +411,13 @@ ati28800_recalctimings(svga_t *svga) if (ati28800->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { - case 0x00: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 42954000.0; - break; - case 0x01: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 48771000.0; - break; - case 0x02: - ati28800_log("clock 2\n"); - break; - case 0x03: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; - break; - case 0x04: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x05: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56640000.0; - break; - case 0x06: - ati28800_log("clock 2\n"); - break; - case 0x07: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - break; - case 0x08: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 30240000.0; - break; - case 0x09: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 32000000.0; - break; - case 0x0A: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 37500000.0; - break; - case 0x0B: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 39000000.0; - break; - case 0x0C: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 0x0D: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 56644000.0; - break; - case 0x0E: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 75000000.0; - break; - case 0x0F: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; - break; - default: - break; - } - if (ati28800->regs[0xb8] & 0x40) svga->clock *= 2; if (ati28800->regs[0xa7] & 0x80) svga->clock *= 3; - if (ati28800->regs[0xb6] & 0x10) { + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; @@ -476,10 +426,24 @@ ati28800_recalctimings(svga_t *svga) if (ati28800->regs[0xb0] & 0x20) { svga->gdcreg[5] |= 0x40; - } - - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((ati28800->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((ati28800->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + ati28800_log("SEQREG1 bit 3=%x. gdcreg5 bits 5-6=%02x, 4bit pel=%02x, planar 16color=%02x, apa mode=%02x, attregs10 bit 7=%02x.\n", svga->seqregs[1] & 8, svga->gdcreg[5] & 0x60, ati28800->regs[0xb3] & 0x40, ati28800->regs[0xac] & 0x40, ati28800->regs[0xb6] & 0x18, ati28800->svga.attrregs[0x10] & 0x80); switch (svga->gdcreg[5] & 0x60) { case 0x00: if (svga->seqregs[1] & 8) /*Low res (320)*/ @@ -502,8 +466,10 @@ ati28800_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; case 15: @@ -516,7 +482,6 @@ ati28800_recalctimings(svga_t *svga) svga->ma_latch <<= 1; } break; - default: break; } @@ -586,6 +551,8 @@ ati28800k_init(const device_t *info) ati28800k_in, ati28800k_out, NULL, NULL); + ati28800->svga.clock_gen = device_add(&ati18810_device); + ati28800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); @@ -652,6 +619,8 @@ ati28800_init(const device_t *info) ati28800_in, ati28800_out, NULL, NULL); + ati28800->svga.clock_gen = device_add(&ati18810_device); + ati28800->svga.getclock = ics2494_getclock; io_sethandler(0x01ce, 2, ati28800_in, NULL, NULL, diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 5b8dedfbea7..e9118bfbc96 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -2579,15 +2579,30 @@ mach_recalctimings(svga_t *svga) if (mach->regs[0xb0] & 0x40) svga->ma_latch |= 0x20000; - if (mach->regs[0xb6] & 0x10) { + if ((mach->regs[0xb6] & 0x18) >= 0x10) { svga->hdisp <<= 1; svga->htotal <<= 1; svga->rowoffset <<= 1; svga->gdcreg[5] &= ~0x40; } - if (mach->regs[0xb0] & 0x20) + if (mach->regs[0xb0] & 0x20) { svga->gdcreg[5] |= 0x40; + if ((mach->regs[0xb6] & 0x18) >= 0x10) + svga->packed_4bpp = 1; + else + svga->packed_4bpp = 0; + } else + svga->packed_4bpp = 0; + + if ((dev->local & 0xff) < 0x02) { + if ((mach->regs[0xb6] & 0x18) == 8) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->ati_4color = 1; + } else + svga->ati_4color = 0; + } mach_log("ON[0]=%d, ON[1]=%d, exton[0]=%d, exton[1]=%d, vendormode0=%d, vendormode1=%d.\n", dev->on[0], dev->on[1], mach->ext_on[0], mach->ext_on[1], dev->vendor_mode[0], dev->vendor_mode[1]); if (dev->on[0] || dev->on[1]) { @@ -2606,9 +2621,6 @@ mach_recalctimings(svga_t *svga) if (dev->dispend == 598) dev->dispend += 2; - if (dev->h_disp == 1024) - dev->accel.advfunc_cntl |= 4; /*Bit 2 means high resolution e.g.: 1024x768*/ - if (dev->accel.advfunc_cntl & 4) { if (mach->shadow_set & 2) { if (dev->h_disp == 8) { @@ -2784,8 +2796,10 @@ mach_recalctimings(svga_t *svga) svga->render = svga_render_8bpp_lowres; else { svga->render = svga_render_8bpp_highres; - svga->ma_latch <<= 1; - svga->rowoffset <<= 1; + if (!svga->packed_4bpp) { + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } } break; } @@ -3628,7 +3642,9 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x6e8: case 0x6e9: if (!(port & 1)) { - if (!dev->on[0] || !dev->on[1]) + if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) + dev->hdisp = val; + else if (!dev->on[0] || !dev->on[1]) dev->hdisp = val; mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); @@ -3655,10 +3671,13 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x16e8: case 0x16e9: - if (!dev->on[0] || !dev->on[1]) { + if ((dev->vendor_mode[0] || dev->vendor_mode[1]) && ((mach->shadow_set & 3) == 0)) { + WRITE8(port, dev->vdisp, val); + } else if (!dev->on[0] || !dev->on[1]) { WRITE8(port, dev->vdisp, val); - dev->vdisp &= 0x1fff; } + dev->vdisp &= 0x1fff; + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", (dev->vdisp >> 1) + 1); svga_recalctimings(svga); break; @@ -3848,7 +3867,8 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x5aef: WRITE8(port, mach->shadow_set, val); mach_log("ATI 8514/A: (0x%04x) val = %04x.\n", port, val); - svga_recalctimings(svga); + if (mach->shadow_set & 3) + svga_recalctimings(svga); break; case 0x5eee: From b38847915cbf712ec3980660ce248c6cdcebaad7 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 27 Dec 2023 13:54:01 -0300 Subject: [PATCH 088/146] Fix game port initialization order issue --- src/86box.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/86box.c b/src/86box.c index 25b073fda92..022e846577c 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1153,9 +1153,6 @@ pc_reset_hard_init(void) * that will be a call to device_reset_all() later ! */ - if (joystick_type) - gameport_update_joystick_type(); - /* Reset and reconfigure the Sound Card layer. */ sound_card_reset(); @@ -1199,10 +1196,13 @@ pc_reset_hard_init(void) /* Reset any ISA RTC cards. */ isartc_reset(); - /* Initialize the Voodoo cards here inorder to minmize + /* Initialize the Voodoo cards here inorder to minimize the chances of the SCSI controller ending up on the bridge. */ video_voodoo_init(); + if (joystick_type) + gameport_update_joystick_type(); /* installs game port if no device provides one, must be late */ + ui_sb_update_panes(); if (config_changed) { From db45cb8c0b3305af282139f2aa7ed5acc6c47326 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 18:40:29 +0100 Subject: [PATCH 089/146] Forgot one file to commit in the branch. --- src/video/vid_svga_render.c | 50 +++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index e3f4bff5e9d..3b02110e3c3 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -35,7 +35,7 @@ svga_lookup_lut_ram(svga_t* svga, uint32_t val) { if (!svga->lut_map) return val; - + uint8_t r = getcolr(svga->pallook[getcolr(val)]); uint8_t g = getcolg(svga->pallook[getcolg(val)]); uint8_t b = getcolb(svga->pallook[getcolb(val)]); @@ -466,11 +466,12 @@ static void svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) { int x; + int xx = 0; uint32_t addr; uint32_t *p; uint32_t changed_offset; - const bool blinked = svga->blink & 0x10; + const bool blinked = !!(svga->blink & 0x10); const bool attrblink = (!svga->disable_blink) && ((svga->attrregs[0x10] & 0x08) != 0); /* @@ -499,11 +500,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) const uint32_t loadevery = forcepacked ? 1 : (dwordload ? 4 : wordload ? 2 : 1); const bool shift4bit = ((svga->gdcreg[0x05] & 0x40) == 0x40) || highres8bpp; - const bool shift2bit = ((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit; + const bool shift2bit = (((svga->gdcreg[0x05] & 0x60) == 0x20) && !shift4bit); const int dwshift = highres ? 0 : 1; const int dotwidth = 1 << dwshift; - const int charwidth = dotwidth * (combine8bits ? 4 : 8); + const int charwidth = dotwidth * ((combine8bits && !svga->packed_4bpp) ? 4 : 8); const uint32_t planemask = 0x11111111 * (uint32_t) (svga->plane_mask); const uint32_t blinkmask = (attrblink ? 0x88888888 : 0x0); const uint32_t blinkval = (attrblink && blinked ? 0x88888888 : 0x0); @@ -637,7 +638,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) */ out_edat = ((out_edat & planemask & ~blinkmask) | ((out_edat | ~planemask) & blinkmask & blinkval)) ^ blinkmask; - for (int i = 0; i < 8; i += 2) { + for (int i = 0; i < (8 + (svga->ati_4color ? 8 : 0)); i += (svga->ati_4color ? 4 : 2)) { /* c0 denotes the first 4bpp pixel shifted, while c1 denotes the second. For 8bpp modes, the first 4bpp pixel is the upper 4 bits. @@ -648,11 +649,37 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) current_shift >>= 3; if (combine8bits) { - uint32_t ccombined = (c0 << 4) | c1; - uint32_t p0 = svga->map8[ccombined]; - const int outoffs = (i >> 1) << dwshift; - for (int subx = 0; subx < dotwidth; subx++) - p[outoffs + subx] = p0; + if (svga->packed_4bpp) { + uint32_t p0 = svga->map8[c0]; + uint32_t p1 = svga->map8[c1]; + const int outoffs = i << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + dotwidth] = p1; + } else { + uint32_t ccombined = (c0 << 4) | c1; + uint32_t p0 = svga->map8[ccombined]; + const int outoffs = (i >> 1) << dwshift; + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx] = p0; + } + } else if (svga->ati_4color) { + uint8_t pal4to16[16] = {0, 7, 8 | 0x30, 15 | 0x30, 0, 2, 4, 14 | 0x30, 0, 3, 4, 15 | 0x30, 0, 3, 5, 15 | 0x30}; + uint8_t *cur_pal = &(pal4to16[svga->color_2bpp << 2]); + uint32_t q[4]; + q[0] = svga->pallook[svga->egapal[cur_pal[(c0 & 0x0c) >> 2]]]; + q[1] = svga->pallook[svga->egapal[cur_pal[c0 & 0x03]]]; + q[2] = svga->pallook[svga->egapal[cur_pal[(c1 & 0x0c) >> 2]]]; + q[3] = svga->pallook[svga->egapal[cur_pal[c1 & 0x03]]]; + + const int outoffs = i << dwshift; + for (int ch = 0; ch < 4; ch++) { + for (int subx = 0; subx < (dotwidth + 1); subx++) + p[outoffs + subx] = q[ch]; + + p += (dotwidth + 1); + } } else { uint32_t p0 = svga->pallook[svga->egapal[c0]]; uint32_t p1 = svga->pallook[svga->egapal[c1]]; @@ -664,7 +691,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } - p += charwidth; + if (!svga->ati_4color) + p += charwidth; } } From 979198d5928b0e7f34207d88733e684feac414fe Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 27 Dec 2023 21:01:25 +0100 Subject: [PATCH 090/146] More ATI changes plus one IBM 8514/A fix: 1. Made the 4 color mode (67h) work properly now, including its 4 schemes on all ATI cards that support said mode. 2. Shadow set now has a true purpose for 8514/A compatibility on ATI Mach8/32. 3. Non-ATI 8514/A used to not work before because of the dev->local variable was not being set to 0 in the ibm8514_init() function, now it's fixed. --- src/include/86box/vid_svga.h | 2 +- src/video/vid_8514a.c | 9 +++++---- src/video/vid_svga.c | 23 +++++++++++---------- src/video/vid_svga_render.c | 39 ++++++++++++++++++------------------ 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 3e7c6f3fe22..4d553900507 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -289,7 +289,7 @@ extern uint8_t ibm8514_ramdac_in(uint16_t port, void *priv); extern void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *priv); extern int ibm8514_cpu_src(svga_t *svga); extern int ibm8514_cpu_dest(svga_t *svga); -extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint16_t val, int len); +extern void ibm8514_accel_out_pixtrans(svga_t *svga, uint16_t port, uint32_t val, int len); extern void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, uint8_t ssv, int len); extern void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len); diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 469a4555ea6..e2a7da3caec 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -221,7 +221,7 @@ ibm8514_cpu_dest(svga_t *svga) } void -ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint16_t val, int len) +ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t nibble = 0; @@ -1298,8 +1298,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - if (dev->accel.cmd == 0x53b1 && !cpu_dat) - ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frgdmix = %02x, bkgdmix = %02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_mix, bkgd_mix, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix); + if (dev->accel.cmd == 0x43b3) { + ibm8514_log("CMD8514: CMD=%d, full=%04x, pixcntl=%x, count=%d, frcolor=%02x, bkcolor=%02x, polygon=%x, cpu=%08x, frgdmix=%02x, bkgdmix=%02x.\n", cmd, dev->accel.cmd, pixcntl, count, frgd_color, bkgd_color, dev->accel.multifunc[0x0a] & 6, cpu_dat, dev->accel.frgd_mix, dev->accel.bkgd_mix); + } switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -3758,7 +3759,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (dev->accel.cmd & 4) { if (dev->accel.sx > 0) { WRITE(dev->accel.dest + dev->accel.dx, dest_dat); @@ -4356,6 +4356,7 @@ ibm8514_init(const device_t *info) dev->changedvram = calloc(dev->vram_size >> 12, 1); dev->vram_mask = dev->vram_size - 1; dev->map8 = dev->pallook; + dev->local = 0; dev->type = info->flags; dev->bpp = 0; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9f125fb728b..71109ce0e45 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -116,6 +116,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) xga_t *xga = (xga_t *) svga->xga; uint8_t o; uint8_t index; + uint8_t pal4to16[16] = { 0, 7, 0x38, 0x3f, 0, 3, 4, 0x3f, 0, 2, 4, 0x3e, 0, 3, 5, 0x3f }; if (!dev && (addr >= 0x2ea) && (addr <= 0x2ed)) return; @@ -163,7 +164,7 @@ svga_out(uint16_t addr, uint8_t val, void *priv) case 0x3c0: case 0x3c1: if (!svga->attrff) { - svga->attraddr = val & 31; + svga->attraddr = val & 0x1f; if ((val & 0x20) != svga->attr_palette_enable) { svga->fullchange = 3; svga->attr_palette_enable = val & 0x20; @@ -172,19 +173,19 @@ svga_out(uint16_t addr, uint8_t val, void *priv) } else { if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) svga->fullchange = svga->monitor->mon_changeframecount; - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) { - svga->color_2bpp = (val >> 4) & 0x03; + o = svga->attrregs[svga->attraddr & 0x1f]; + svga->attrregs[svga->attraddr & 0x1f] = val; + if (svga->attraddr < 0x10) svga->fullchange = svga->monitor->mon_changeframecount; - } - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (int c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) { + + if ((svga->attraddr == 0x10) || (svga->attraddr == 0x14) || (svga->attraddr < 0x10)) { + for (int c = 0; c < 0x10; c++) { + if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - } else { + else if (svga->ati_4color) + svga->egapal[c] = pal4to16[(c & 0x03) | ((val >> 2) & 0xc)]; + else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } } svga->fullchange = svga->monitor->mon_changeframecount; } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 3b02110e3c3..291a97f2b5a 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -586,8 +586,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) But 4bpp chunky is generally easier to deal with on a modern CPU. shift4bit is the native format for this renderer (4bpp chunky). */ - if (!shift4bit) { - if (shift2bit) { + if (svga->ati_4color || !shift4bit) { + if (shift2bit && !svga->ati_4color) { /* Group 2x 2bpp values into 4bpp values */ edat = (edat & 0xCCCC3333) | ((edat << 14) & 0x33330000) | ((edat >> 14) & 0x0000CCCC); } else { @@ -648,7 +648,19 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t c1 = (out_edat >> (current_shift & 0x1C)) & 0xF; current_shift >>= 3; - if (combine8bits) { + if (svga->ati_4color) { + uint32_t q[4]; + q[0] = svga->pallook[svga->egapal[(c0 & 0x0c) >> 2]]; + q[1] = svga->pallook[svga->egapal[c0 & 0x03]]; + q[2] = svga->pallook[svga->egapal[(c1 & 0x0c) >> 2]]; + q[3] = svga->pallook[svga->egapal[c1 & 0x03]]; + + const int outoffs = i << dwshift; + for (int ch = 0; ch < 4; ch++) { + for (int subx = 0; subx < dotwidth; subx++) + p[outoffs + subx + (dotwidth * ch)] = q[ch]; + } + } else if (combine8bits) { if (svga->packed_4bpp) { uint32_t p0 = svga->map8[c0]; uint32_t p1 = svga->map8[c1]; @@ -664,22 +676,6 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; } - } else if (svga->ati_4color) { - uint8_t pal4to16[16] = {0, 7, 8 | 0x30, 15 | 0x30, 0, 2, 4, 14 | 0x30, 0, 3, 4, 15 | 0x30, 0, 3, 5, 15 | 0x30}; - uint8_t *cur_pal = &(pal4to16[svga->color_2bpp << 2]); - uint32_t q[4]; - q[0] = svga->pallook[svga->egapal[cur_pal[(c0 & 0x0c) >> 2]]]; - q[1] = svga->pallook[svga->egapal[cur_pal[c0 & 0x03]]]; - q[2] = svga->pallook[svga->egapal[cur_pal[(c1 & 0x0c) >> 2]]]; - q[3] = svga->pallook[svga->egapal[cur_pal[c1 & 0x03]]]; - - const int outoffs = i << dwshift; - for (int ch = 0; ch < 4; ch++) { - for (int subx = 0; subx < (dotwidth + 1); subx++) - p[outoffs + subx] = q[ch]; - - p += (dotwidth + 1); - } } else { uint32_t p0 = svga->pallook[svga->egapal[c0]]; uint32_t p1 = svga->pallook[svga->egapal[c1]]; @@ -691,7 +687,10 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } - if (!svga->ati_4color) + if (svga->ati_4color) + p += (charwidth << 1); + // p += charwidth; + else p += charwidth; } } From 87f5d01fda8bef85459c4942fcc7afb94abbc83e Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:13:55 +0100 Subject: [PATCH 091/146] Unix: Separate XDG_DATA_DIRS paths by colon instead of semicolon, fixes #3946. --- src/unix/unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index cf69997b09f..0a71ac8739a 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -816,7 +816,7 @@ plat_init_rom_paths(void) while (xdg_rom_paths[strlen(xdg_rom_paths) - 1] == ':') { xdg_rom_paths[strlen(xdg_rom_paths) - 1] = '\0'; } - while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ";")) != NULL) { + while ((cur_xdg_rom_path = local_strsep(&xdg_rom_paths, ":")) != NULL) { char real_xdg_rom_path[1024] = { '\0' }; strcat(real_xdg_rom_path, cur_xdg_rom_path); path_slash(real_xdg_rom_path); From 3483cb02b36d4864c31920763f4dc6cd29b88c16 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:15:07 +0100 Subject: [PATCH 092/146] Removed an unused variable from video/vid_svga_render.c. --- src/video/vid_svga_render.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 291a97f2b5a..20c1e6e5e83 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -466,7 +466,6 @@ static void svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) { int x; - int xx = 0; uint32_t addr; uint32_t *p; uint32_t changed_offset; From dd005d74ea43d8f02e91d26a8d295f3494fa430a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:30:47 +0100 Subject: [PATCH 093/146] Unix SDL: Fix plat_pause(). --- src/unix/unix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index 0a71ac8739a..1314db5866f 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -762,10 +762,13 @@ plat_pause(int p) static wchar_t oldtitle[512]; wchar_t title[512]; + if ((!!p) == dopause) + return; + if ((p == 0) && (time_sync & TIME_SYNC_ENABLED)) nvr_time_sync(); - dopause = p; + do_pause(p); if (p) { wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); wcscpy(title, oldtitle); From b239f4c102b09df2fda76b038795b3b7e8a4dbfd Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:35:39 +0100 Subject: [PATCH 094/146] Unix SDL: Actually honor the return value of pc_init(), fixes #3948. --- src/unix/unix.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index 1314db5866f..3ca0a4e17bb 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1163,9 +1163,12 @@ main(int argc, char **argv) { SDL_Event event; void *libedithandle; + int ret = 0; SDL_Init(0); - pc_init(argc, argv); + ret = pc_init(argc, argv); + if (ret == 0) + return 0; if (!pc_init_modules()) { ui_msgbox_header(MBX_FATAL, L"No ROMs found.", L"86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory."); SDL_Quit(); From 62917d5ef63701627eca0876cf5781399226a463 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:39:23 +0100 Subject: [PATCH 095/146] Unix SDL: Unpause the main window after initialization, fixes #3940. --- src/unix/unix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/unix/unix.c b/src/unix/unix.c index 3ca0a4e17bb..b35820543ae 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1212,6 +1212,7 @@ main(int argc, char **argv) thread_create(monitor_thread, NULL); #endif SDL_AddTimer(1000, timer_onesec, NULL); + plat_pause(1); while (!is_quit) { static int mouse_inside = 0; From 46d01e30da64ebab28c95f773edbc01e62d996c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 27 Dec 2023 21:39:51 +0100 Subject: [PATCH 096/146] Actually unpause it at the correct time. --- src/unix/unix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/unix/unix.c b/src/unix/unix.c index b35820543ae..2e76ee5a9b5 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1203,7 +1203,7 @@ main(int argc, char **argv) pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ - // plat_pause(0); + plat_pause(0); /* Initialize the rendering window, or fullscreen. */ @@ -1212,7 +1212,6 @@ main(int argc, char **argv) thread_create(monitor_thread, NULL); #endif SDL_AddTimer(1000, timer_onesec, NULL); - plat_pause(1); while (!is_quit) { static int mouse_inside = 0; From d9dfa8d8d5116ab89b8134512103694e56f72509 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 28 Dec 2023 02:01:45 +0100 Subject: [PATCH 097/146] More ATI accel fixes and undocumented stuff. 1. Apparently some stuff uses read-only port 0x86ee and expects it to return 0 while port 0xf6ee is an alias to 0x82e8, this should fix hangs in Majong 8514 using ATI's DOS drivers. 2. 8514 data available bits are reset properly when new parameters for a new command are installed (port 0xCEEE), fixes remaining hangs with some stuff. --- src/video/vid_ati_mach8.c | 47 +++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index e9118bfbc96..1fca8336999 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -135,8 +135,9 @@ typedef struct mach_t { uint16_t scratch1; uint16_t test; uint16_t pattern; - uint8_t test2[2]; - uint8_t test3[2]; + uint16_t test2; + uint16_t test3; + uint16_t test4; int src_y_dir; int cmd_type; int block_write_mono_pattern_enable; @@ -1361,7 +1362,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 return; } if (dev->accel.sy >= mach->accel.height) { - if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 2) || (frgd_sel == 3) || (bkgd_sel == 2) || (bkgd_sel == 3)) + if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) return; if ((mono_src == 1) && (frgd_sel == 5) && (dev->accel_bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) return; @@ -2623,7 +2624,7 @@ mach_recalctimings(svga_t *svga) if (dev->accel.advfunc_cntl & 4) { if (mach->shadow_set & 2) { - if (dev->h_disp == 8) { + if ((dev->h_disp == 8) && !dev->bpp) { dev->h_disp = 1024; dev->dispend = 768; dev->v_total = 1536; @@ -2634,7 +2635,7 @@ mach_recalctimings(svga_t *svga) } else svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((mach->accel.clock_sel >> 2) & 0x0f, svga->clock_gen); } else { - if (dev->h_disp == 1024) { + if ((dev->h_disp == 1024) && !dev->bpp) { dev->h_disp = 640; dev->dispend = 480; } @@ -2819,9 +2820,12 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u int bkgd_sel; int mono_src; + mach_log("[%04X:%08X]: Port FIFO OUT=%04x, val=%04x, len=%d.\n", CS, cpu_state.pc, port, val, len); + switch (port) { case 0x82e8: case 0xc2e8: + case 0xf6ee: if (len == 1) { dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; } else { @@ -2830,6 +2834,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u break; case 0x82e9: case 0xc2e9: + case 0xf6ef: if (len == 1) { dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); } @@ -3497,6 +3502,8 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u if (len == 1) mach->accel.dp_config = (mach->accel.dp_config & 0xff00) | val; else { + dev->data_available = 0; + dev->data_available2 = 0; mach->accel.dp_config = val; } break; @@ -3631,7 +3638,7 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - mach_log("Port accel out = %04x, val = %04x.\n", port, val); + mach_log("[%04X:%08X]: Port NORMAL OUT=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); switch (port) { case 0x2e8: @@ -3830,12 +3837,12 @@ mach_accel_out(uint16_t port, uint8_t val, mach_t *mach) case 0x42ee: case 0x42ef: - mach->accel.test2[port & 1] = val; + WRITE8(port, mach->accel.test2, val); break; case 0x46ee: case 0x46ef: - mach->accel.test3[port & 1] = val; + WRITE8(port, mach->accel.test3, val); break; case 0x4aee: @@ -4183,6 +4190,11 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in temp = mach->accel.patt_data_idx; break; + case 0x86ee: + case 0x86ef: + temp = 0x0000; + break; + case 0x8eee: if (len == 1) temp = mach->accel.ext_ge_config & 0xff; @@ -4352,7 +4364,7 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in break; } - mach_log("Port FIFO IN=%04x, temp=%04x, len=%d.\n", port, temp, len); + mach_log("[%04X:%08X]: Port FIFO IN=%04x, temp=%04x, len=%d.\n", CS, cpu_state.pc, port, temp, len); return temp; } @@ -4362,8 +4374,8 @@ mach_accel_in(uint16_t port, mach_t *mach) svga_t *svga = &mach->svga; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; uint8_t temp = 0; - int vpos = 0; - int vblankend = svga->vblankstart + svga->crtc[0x16]; + uint16_t vpos = 0; + uint16_t vblankend = svga->vblankstart + svga->crtc[0x16]; switch (port) { case 0x2e8: @@ -4469,17 +4481,13 @@ mach_accel_in(uint16_t port, mach_t *mach) break; case 0x42ee: - temp = mach->accel.test2[0]; - break; case 0x42ef: - temp = mach->accel.test2[1]; + READ8(port, mach->accel.test2); break; case 0x46ee: - temp = mach->accel.test3[0]; - break; case 0x46ef: - temp = mach->accel.test3[1]; + READ8(port, mach->accel.test3); break; case 0x4aee: @@ -4547,7 +4555,7 @@ mach_accel_in(uint16_t port, mach_t *mach) default: break; } - mach_log("Port accel in = %04x, temp = %04x.\n", port, temp); + mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); return temp; } @@ -5478,6 +5486,7 @@ mach_io_set(mach_t *mach) io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0x86ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); @@ -5502,6 +5511,7 @@ mach_io_set(mach_t *mach) io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); + io_sethandler(0xf6ee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, mach_accel_inl, mach_accel_outb, mach_accel_outw, mach_accel_outl, mach); } @@ -5781,7 +5791,6 @@ mach8_init(const device_t *info) else mach->config1 |= 0x06; mach->config1 |= 0x0400; - mach->config1 |= 0x1000; svga->clock_gen = device_add(&ati18811_1_device); } else if (mach->pci_bus) { video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_pci); From e614103f04ef3fe9dbce1006f0ae5232f423bd29 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 11:38:34 +0100 Subject: [PATCH 098/146] Unix: Temporarily disable the use of f_readline, fixes #3949. --- src/unix/unix.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/unix/unix.c b/src/unix/unix.c index 2e76ee5a9b5..e784df38e62 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -917,12 +917,16 @@ monitor_thread(void *param) while (!exit_event) { if (feof(stdin)) break; +#ifdef ENABLE_READLINE if (f_readline) line = f_readline("(86Box) "); else { +#endif printf("(86Box) "); (void) !getline(&line, &n, stdin); +#ifdef ENABLE_READLINE } +#endif if (line) { int cmdargc = 0; char *linecpy; From b877c0c6396c0428c1070871a4425fd9df0522fd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 11:45:53 +0100 Subject: [PATCH 099/146] Disable --settings when using the SDL UI, closes #3950. --- src/86box.c | 4 ++++ src/CMakeLists.txt | 1 + 2 files changed, 5 insertions(+) diff --git a/src/86box.c b/src/86box.c index bf6e8d94ae5..2e9434b826c 100644 --- a/src/86box.c +++ b/src/86box.c @@ -542,7 +542,9 @@ pc_init(int argc, char *argv[]) printf("-N or --noconfirm - do not ask for confirmation on quit\n"); printf("-P or --vmpath path - set 'path' to be root for vm\n"); printf("-R or --rompath path - set 'path' to be ROM path\n"); +#ifndef USE_SDL_UI printf("-S or --settings - show only the settings dialog\n"); +#endif printf("-V or --vmname name - overrides the name of the running VM\n"); printf("-X or --clear what - clears the 'what' (cmos/flash/both)\n"); printf("-Y or --donothing - do not show any UI or run the emulation\n"); @@ -609,8 +611,10 @@ pc_init(int argc, char *argv[]) goto usage; strcpy(vm_name, argv[++c]); +#ifndef USE_SDL_UI } else if (!strcasecmp(argv[c], "--settings") || !strcasecmp(argv[c], "-S")) { settings_only = 1; +#endif } else if (!strcasecmp(argv[c], "--noconfirm") || !strcasecmp(argv[c], "-N")) { confirm_exit_cmdl = 0; } else if (!strcasecmp(argv[c], "--missing") || !strcasecmp(argv[c], "-M")) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bfa582e33f5..ec32d7548a8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -229,5 +229,6 @@ if (QT) elseif(WIN32) add_subdirectory(win) else() + add_compile_definitions(USE_SDL_UI) add_subdirectory(unix) endif() From 8e50e88f7e4427c33f58b6a38ccbddbedf43acc9 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 28 Dec 2023 21:20:15 +0500 Subject: [PATCH 100/146] Joystick: Fix emulated POV hat configuration --- src/qt/qt_joystickconfiguration.cpp | 10 +--------- src/qt/qt_settingsinput.cpp | 4 ++-- src/win/win_jsconf.c | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index 8523a258dda..c363cd54488 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -186,7 +186,7 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) Models::AddEntry(model, plat_joystick_state[joystick].axis[d].name, 0); } - int mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + int mapping = joystick_state[joystick_nr].pov_mapping[c / 2][c & 1]; int nr_povs = plat_joystick_state[joystick].nr_povs; if (mapping & POV_X) cbox->setCurrentIndex((mapping & 3) * 2); @@ -195,14 +195,6 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) else cbox->setCurrentIndex(mapping + nr_povs * 2); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - cbox->setCurrentIndex((mapping & 3) * 2); - else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3) * 2 + 1); - else - cbox->setCurrentIndex(mapping + nr_povs * 2); - ui->ct->addWidget(label, row, 0); ui->ct->addWidget(cbox, row, 1); diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index 66d6e3de046..34d111e101c 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -190,9 +190,9 @@ updateJoystickConfig(int type, int joystick_nr, QWidget *parent) for (int c = 0; c < joystick_get_button_count(type); c++) { joystick_state[joystick_nr].button_mapping[c] = jc.selectedButton(c); } - for (int c = 0; c < joystick_get_button_count(type); c++) { + for (int c = 0; c < joystick_get_pov_count(type) * 2; c += 2) { joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(jc, c, joystick_nr); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c, joystick_nr); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(jc, c + 1, joystick_nr); } } } diff --git a/src/win/win_jsconf.c b/src/win/win_jsconf.c index 190338d3e14..66ad60c7392 100644 --- a/src/win/win_jsconf.c +++ b/src/win/win_jsconf.c @@ -247,7 +247,7 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lPa joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); id += 2; } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { h = GetDlgItem(hdlg, id); joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); id += 2; From c255bd51611cd392ae2e18df634ef1970e402a50 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 18:34:35 +0100 Subject: [PATCH 101/146] Attempted fix for SCSI disk seek timings. --- src/include/86box/hdd.h | 4 ++-- src/scsi/scsi_disk.c | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 8c82209c7f5..89a6cf1ffbe 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -159,8 +159,8 @@ typedef struct hard_disk_t { char fn[1024]; /* Name of current image file */ char vhd_parent[1041]; /* Differential VHD parent file */ - uint32_t res0; - uint32_t pad1; + uint32_t seek_pos; + uint32_t seek_len; uint32_t base; uint32_t spt; uint32_t hpc; /* Physical geometry parameters */ diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 837800eb052..39a69ea3233 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -446,7 +446,7 @@ scsi_disk_command_common(scsi_disk_t *dev) case GPCMD_WRITE_AND_VERIFY_12: case GPCMD_WRITE_SAME_10: /* Seek time is in us. */ - period = hdd_timing_write(dev->drv, dev->sector_pos, dev->packet_len >> 9); + period = hdd_timing_write(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); dev->callback += period; @@ -482,7 +482,7 @@ scsi_disk_command_common(scsi_disk_t *dev) case 0x28: case 0xa8: /* Seek time is in us. */ - period = hdd_timing_read(dev->drv, dev->sector_pos, dev->packet_len >> 9); + period = hdd_timing_read(dev->drv, dev->drv->seek_pos, dev->drv->seek_len); scsi_disk_log("SCSI HD %i: Seek period: %" PRIu64 " us\n", dev->id, (uint64_t) period); dev->callback += period; @@ -928,6 +928,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) case GPCMD_REZERO_UNIT: dev->sector_pos = dev->sector_len = 0; + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + scsi_disk_seek(dev, 0); scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); break; @@ -1031,6 +1035,9 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) dev->packet_len = max_len * alloc_length; scsi_disk_buf_alloc(dev, dev->packet_len); + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + ret = scsi_disk_blocks(dev, &alloc_length, 1, 0); if (ret <= 0) { scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); @@ -1118,6 +1125,9 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) break; } + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = dev->sector_len; + max_len = dev->sector_len; /* If we're writing all blocks in one go for DMA, why not also for @@ -1371,6 +1381,10 @@ scsi_disk_command(scsi_common_t *sc, uint8_t *cdb) default: break; } + + dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_len = 0; + scsi_disk_seek(dev, pos); scsi_disk_set_phase(dev, SCSI_PHASE_STATUS); From 137581c0809336c41a0a872a6b930d92d9dd84a1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 18:42:16 +0100 Subject: [PATCH 102/146] Fix for CD-ROM timings - seek times are no longer always calculated as if it was seeking from sector 0. --- src/scsi/scsi_cdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index fb52ca8984b..d2a6170a687 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -1751,7 +1751,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) int used_len; int alloc_length; int msf; - int pos = 0; + int pos = dev->drv->seek_pos; int size_idx; int idx = 0; uint32_t feature; From 277581daeaeb12a021ec8ca32a8f4c66b6c47a9f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 02:13:40 +0600 Subject: [PATCH 103/146] Non-working Millennium II --- src/include/86box/video.h | 1 + src/video/vid_mga.c | 314 +++++++++++++++++++++++++++++++++----- src/video/vid_table.c | 1 + 3 files changed, 274 insertions(+), 42 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index fc739004f28..3d1339f3b79 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -438,6 +438,7 @@ extern const device_t pgc_device; extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; +extern const device_t millennium_ii_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 35354b2ad3d..96b1d75edf7 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -15,6 +15,7 @@ * Copyright 2008-2020 Sarah Walker. */ #include +#include #include #include #include @@ -36,9 +37,10 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" -#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" -#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" +#define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN" +#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" +#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -111,6 +113,13 @@ #define REG_DR14 0x1cf8 #define REG_DR15 0x1cfc +#define REG_DR0_Z32LSB 0x2c50 +#define REG_DR0_Z32MSB 0x2c54 +#define REG_DR2_Z32LSB 0x2c60 +#define REG_DR2_Z32MSB 0x2c64 +#define REG_DR3_Z32LSB 0x2c68 +#define REG_DR3_Z32MSB 0x2c6c + #define REG_FIFOSTATUS 0x1e10 #define REG_STATUS 0x1e14 #define REG_ICLEAR 0x1e18 @@ -309,6 +318,7 @@ #define MACCESS_PWIDTH_16 (1 << 0) #define MACCESS_PWIDTH_32 (2 << 0) #define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_ZWIDTH (1 << 3) #define MACCESS_TLUTLOAD (1 << 29) #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) @@ -383,6 +393,7 @@ enum { MGA_2064W, /*Millennium*/ MGA_1064SG, /*Mystique*/ MGA_1164SG, /*Mystique 220*/ + MGA_2164W, /*Millennium II*/ }; enum { @@ -488,6 +499,8 @@ typedef struct mystique_t { uint32_t src[4], ar[7], dr[16], tmr[9]; + uint64_t extended_dr[4]; + struct { int sdydxl, scanleft, sdxl, sdy, @@ -675,7 +688,7 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) case 0x3c6: case 0x3c7: case 0x3c9: - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { tvp3026_ramdac_out(addr, 0, 0, val, svga->ramdac, svga); return; } @@ -792,7 +805,7 @@ mystique_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (mystique->type == MGA_2064W) + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) temp = tvp3026_ramdac_in(addr, 0, 0, svga->ramdac, svga); else temp = svga_in(addr, svga); @@ -906,7 +919,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) svga->split |= 0x400; - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { tvp3026_recalctimings(svga->ramdac, svga); svga->interlace |= !!(mystique->crtcext_regs[0] & 0x80); } else @@ -1037,7 +1050,7 @@ mystique_recalc_mapping(mystique_t *mystique) mem_mapping_disable(&mystique->ctrl_mapping); if (mystique->lfb_base) - mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, (mystique->type >= MGA_2164W) ? 0x1000000 : 0x800000); else mem_mapping_disable(&mystique->lfb_mapping); @@ -1441,7 +1454,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) int rs2 = 0; int rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) { /*RAMDAC*/ addr_0x0f = addr & 0x0f; @@ -1811,7 +1824,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_YDSTORG + 2: case REG_YDSTORG + 3: WRITE8(addr, mystique->dwgreg.ydstorg, val); - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_YTOP: case REG_YTOP + 1: @@ -2007,7 +2020,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) int rs2 = 0; int rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + if ((mystique->type == MGA_2064W || mystique->type == MGA_2164W) && (addr & 0x3e00) == 0x3c00) { /*RAMDAC*/ addr_0x0f = addr & 0x0f; @@ -2290,7 +2303,7 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_ZORG: mystique->dwgreg.zorg = val; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_PLNWT: @@ -2417,14 +2430,47 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->dwgreg.ar[6] = val; break; + case REG_DR0_Z32LSB: + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR0_Z32MSB: + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR2_Z32LSB: + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR2_Z32MSB: + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[2] = (mystique->dwgreg.extended_dr[2] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR3_Z32LSB: + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFFFFF) | val; + mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF; + break; + + case REG_DR3_Z32MSB: + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & 0xFFFFFFFF) | ((val & 0xFFFFull) << 32ull); + mystique->dwgreg.dr[3] = (mystique->dwgreg.extended_dr[3] >> 16) & 0xFFFFFFFF; + break; + case REG_DR0: mystique->dwgreg.dr[0] = val; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR2: mystique->dwgreg.dr[2] = val; + mystique->dwgreg.extended_dr[2] = (mystique->dwgreg.extended_dr[2] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR3: mystique->dwgreg.dr[3] = val; + mystique->dwgreg.extended_dr[3] = (mystique->dwgreg.extended_dr[3] & ~0xFFFFull) | ((uint64_t)val << 16ull); break; case REG_DR4: mystique->dwgreg.dr[4] = val; @@ -4113,6 +4159,29 @@ z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl } } +static int +z_check_32(uint32_t z, uint32_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +{ + switch (z_mode) { + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); + + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; + } +} + static void blit_line(mystique_t *mystique, int closed) { @@ -4216,18 +4285,30 @@ blit_line(mystique_t *mystique, int closed) x = mystique->dwgreg.xdst; while (mystique->dwgreg.length > 0) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - uint16_t old_z = z_p[x]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t *z_p = (uint32_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 4 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint32_t old_z = z_p[x]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + if (z_write && z_check_pass) { + z_p[x] = z; + } + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t old_z = z_p[x]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + if (z_write && z_check_pass) { + z_p[x] = z; + } + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { int r = 0; int g = 0; int b = 0; - if (z_write) - z_p[x] = z; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_16: if (!(mystique->dwgreg.dr[4] & (1 << 23))) @@ -4253,7 +4334,13 @@ blit_line(mystique_t *mystique, int closed) else mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; @@ -4266,7 +4353,13 @@ blit_line(mystique_t *mystique, int closed) else x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; @@ -4326,6 +4419,7 @@ static void blit_trap(mystique_t *mystique) { svga_t *svga = &mystique->svga; + uint64_t z_back_32; uint32_t z_back; uint32_t r_back; uint32_t g_back; @@ -4491,12 +4585,14 @@ blit_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask]; int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int16_t old_x_l = x_l; int dx; + z_back_32 = mystique->dwgreg.extended_dr[0]; + z_back = mystique->dwgreg.dr[0]; r_back = mystique->dwgreg.dr[4]; g_back = mystique->dwgreg.dr[8]; @@ -4504,10 +4600,18 @@ blit_trap(mystique_t *mystique) while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t old_z = *(uint32_t*)&z_p[x_l * 2]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { uint32_t dst = 0; uint32_t old_dst; int r = 0; @@ -4521,8 +4625,13 @@ blit_trap(mystique_t *mystique) if (!(mystique->dwgreg.dr[12] & (1 << 23))) b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - if (z_write) - z_p[x_l] = z; + if (z_write) { + if (mystique->maccess_running & MACCESS_ZWIDTH) { + *(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + } + else + z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: @@ -4553,7 +4662,13 @@ blit_trap(mystique_t *mystique) } } - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; @@ -4566,7 +4681,13 @@ blit_trap(mystique_t *mystique) mystique->pixel_count++; } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; @@ -4584,7 +4705,13 @@ blit_trap(mystique_t *mystique) mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; @@ -4715,12 +4842,14 @@ blit_texture_trap(mystique_t *mystique) for (y = 0; y < mystique->dwgreg.length; y++) { uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * ((mystique->maccess_running & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg) & mystique->vram_mask]; int16_t x_l = mystique->dwgreg.fxleft & 0xffff; int16_t x_r = mystique->dwgreg.fxright & 0xffff; int16_t old_x_l = x_l; int dx; + uint64_t z_back_32 = mystique->dwgreg.extended_dr[0]; + uint32_t z_back = mystique->dwgreg.dr[0]; uint32_t r_back = mystique->dwgreg.dr[4]; uint32_t g_back = mystique->dwgreg.dr[8]; @@ -4731,10 +4860,18 @@ blit_texture_trap(mystique_t *mystique) while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { - uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + bool z_check_pass = false; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + uint32_t z = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + uint32_t old_z = *(uint32_t*)&z_p[x_l * 2]; + z_check_pass = z_check_32(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } else { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; + z_check_pass = z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK); + } - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + if (z_check_pass) { int tex_r = 0; int tex_g = 0; int tex_b = 0; @@ -4808,8 +4945,13 @@ blit_texture_trap(mystique_t *mystique) ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; } - if (z_write) - z_p[x_l] = z; + if (z_write) { + if (mystique->maccess_running & MACCESS_ZWIDTH) { + *(uint32_t*)(&z_p[x_l * 2]) = (mystique->dwgreg.extended_dr[0] & (1ull << 47ull)) ? 0 : (mystique->dwgreg.extended_dr[0] >> 15ull); + } + else + z_p[x_l] = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + } } } skip_pixel: @@ -4820,7 +4962,13 @@ blit_texture_trap(mystique_t *mystique) mystique->pixel_count++; - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; @@ -4829,7 +4977,13 @@ blit_texture_trap(mystique_t *mystique) mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; @@ -4850,7 +5004,13 @@ blit_texture_trap(mystique_t *mystique) mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + if (mystique->maccess_running & MACCESS_ZWIDTH) { + mystique->dwgreg.extended_dr[0] += dx * mystique->dwgreg.extended_dr[2]; + mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; + } else { + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); + } mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; @@ -5474,6 +5634,15 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; + if (mystique->type >= MGA_2164W) + { + /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + if (addr >= 0x10 && addr <= 0x13) + addr += 0x4; + else if (addr >= 0x14 && addr <= 0x17) + addr -= 0x4; + } + if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) ret = 0x00; else @@ -5486,7 +5655,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x02: - ret = (mystique->type == MGA_2064W) ? 0x19 : 0x1a; + ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); break; /*MGA*/ case 0x03: ret = 0x05; @@ -5537,7 +5706,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) ret = 0x00; break; /*Linear frame buffer*/ case 0x16: - ret = (mystique->lfb_base >> 16) & 0x80; + ret = (mystique->type >= MGA_2164W) ? 0x00 : ((mystique->lfb_base >> 16) & 0x80); break; case 0x17: ret = mystique->lfb_base >> 24; @@ -5626,6 +5795,15 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; + if (mystique->type >= MGA_2164W) + { + /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + if (addr >= 0x10 && addr <= 0x13) + addr += 0x4; + else if (addr >= 0x14 && addr <= 0x17) + addr -= 0x4; + } + switch (addr) { case PCI_REG_COMMAND: mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; @@ -5654,11 +5832,13 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x16: + if (mystique->type >= MGA_2164W) + break; mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); mystique_recalc_mapping(mystique); break; case 0x17: - mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique->lfb_base = (mystique->lfb_base & ((mystique->type >= MGA_2164W) ? 0x00000000 : 0x00800000)) | (val << 24); mystique_recalc_mapping(mystique); break; @@ -5785,6 +5965,8 @@ mystique_init(const device_t *info) if (mystique->type == MGA_2064W) romfn = ROM_MILLENNIUM; + else if (mystique->type == MGA_2164W) + romfn = ROM_MILLENNIUM_II; else if (mystique->type == MGA_1064SG) romfn = ROM_MYSTIQUE; else @@ -5800,7 +5982,7 @@ mystique_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); - if (mystique->type == MGA_2064W) { + if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, mystique_recalctimings, @@ -5945,6 +6127,12 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } +static int +millennium_ii_available(void) +{ + return rom_present(ROM_MILLENNIUM_II); +} + static void mystique_speed_changed(void *priv) { @@ -5993,6 +6181,34 @@ static const device_config_t mystique_config[] = { // clang-format on }; +static const device_config_t millennium_ii_config[] = { + // clang-format off + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "" + } + }, + .default_int = 8 + }, + { + .type = CONFIG_END + } + // clang-format on +}; + const device_t millennium_device = { .name = "Matrox Millennium", .internal_name = "millennium", @@ -6034,3 +6250,17 @@ const device_t mystique_220_device = { .force_redraw = mystique_force_redraw, .config = mystique_config }; + +const device_t millennium_ii_device = { + .name = "Matrox Millennium II", + .internal_name = "millennium_ii", + .flags = DEVICE_PCI, + .local = MGA_2164W, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, + { .available = millennium_ii_available }, + .speed_changed = mystique_speed_changed, + .force_redraw = mystique_force_redraw, + .config = mystique_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index ad6fca2c67d..0532a15a805 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -205,6 +205,7 @@ video_cards[] = { { &s3_diamond_stealth_4000_pci_device }, { &s3_trio3d2x_pci_device }, { &millennium_device }, + { &millennium_ii_device }, { &mystique_device }, { &mystique_220_device }, { &tgui9440_pci_device }, From 3d7923d9540bca71d3c7a8b26e0bfc92ef82065f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:12:21 +0100 Subject: [PATCH 104/146] Added the Dell Dimension XPS Pxxx, LG IBM 440FX (MS-6106), and NEC Mate NX MA30D/23D. --- src/device/CMakeLists.txt | 2 +- src/device/nec_mate_unk.c | 76 +++++++++++++++++++++++++++++++++++ src/include/86box/machine.h | 3 ++ src/machine/m_at_socket7_3v.c | 36 ++++++++++++++++- src/machine/m_at_socket8.c | 29 +++++++++++++ src/win/Makefile.mingw | 3 +- 6 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 src/device/nec_mate_unk.c diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 2988152c12d..9e2c2b53dc3 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(dev OBJECT bugger.c cassette.c cartridge.c hasp.c hwm.c hwm_lm75.c h smbus_piix4.c smbus_ali7101.c keyboard.c keyboard_xt.c kbc_at.c kbc_at_dev.c keyboard_at.c - mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c phoenix_486_jumper.c + mouse.c mouse_bus.c mouse_serial.c mouse_ps2.c nec_mate_unk.c phoenix_486_jumper.c serial_passthrough.c) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c new file mode 100644 index 00000000000..d49805fc88f --- /dev/null +++ b/src/device/nec_mate_unk.c @@ -0,0 +1,76 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NEC Mate NX MA30D/23D Unknown Readout. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2020-2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include <86box/io.h> +#include <86box/device.h> +#include <86box/chipset.h> +#include <86box/plat_unused.h> + + if ((port == 0x6b) || (port == 0x3d6d)) + ret = 0x2a; + +static uint8_t +nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) +{ + /* Expected by this NEC machine. + + It writes something on ports 3D6C, 3D6D, and 3D6E, then expects to read + 2Ah from port 3D6D. Then it repeats this with ports 6A, 6B, and 6C. + */ + return 0x2a; +} + +static void +nec_mate_unk_close(void *priv) +{ + free(dev); +} + +static void * +nec_mate_unk_init(const device_t *info) +{ + /* We have to return something non-NULL. */ + uint8_t *dev = (uint8_t *) calloc(1, sizeof(uint8_t)); + + io_sethandler(0x006b, 0x0001, nec_mate_unk_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x3d6d, 0x0001, nec_mate_unk_read, NULL, NULL, NULL, NULL, NULL, NULL); + + return dev; +} + +const device_t nec_mate_unk_device = { + .name = "NEC Mate NX MA30D/23D Unknown Readout", + .internal_name = "nec_mate_unk_jumper", + .flags = 0, + .local = 0, + .init = nec_mate_unk_jumper_init, + .close = nec_mate_unk_jumper_close, + .reset = nec_mate_unk_jumper_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 8560f0d3bd7..d75d65a01a2 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -638,6 +638,7 @@ extern int machine_at_8500tuc_init(const machine_t *); extern int machine_at_p55t2s_init(const machine_t *); extern int machine_at_p5vxb_init(const machine_t *); +extern int machine_at_dell_430vx_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); extern int machine_at_ap5s_init(const machine_t *); @@ -706,6 +707,7 @@ extern int machine_at_aurora_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); extern int machine_at_acerv60n_init(const machine_t *); +extern int machine_at_lgibm440fx_init(const machine_t *); extern int machine_at_vs440fx_init(const machine_t *); extern int machine_at_gw2kvenus_init(const machine_t *); extern int machine_at_ap440fx_init(const machine_t *); @@ -759,6 +761,7 @@ extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_m773_init(const machine_t *); extern int machine_at_ambx133_init(const machine_t *); extern int machine_at_awo671r_init(const machine_t *); +extern int machine_at_lc500j34dr_init(const machine_t *); extern int machine_at_63a1_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index de87ec90d9c..a1b6de3251f 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -671,6 +671,40 @@ machine_at_p5vxb_init(const machine_t *model) return ret; } +int +machine_at_dell_430vx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/dell_430vx/1003DY0J.BIO", + "roms/machines/dell_430vx/1003DY0J.BI1", + "roms/machines/dell_430vx/1003DY0J.BI2", + "roms/machines/dell_430vx/1003DY0J.BI3", + "roms/machines/dell_430vx/1003DY0J.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); + device_add(&i430vx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c932fr_device); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + int machine_at_gw2kte_init(const machine_t *model) { @@ -694,7 +728,7 @@ machine_at_gw2kte_init(const machine_t *model) pci_register_slot(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); device_add(&i430vx_device); device_add(&piix3_device); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 628206a61c7..6e63af73290 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -161,6 +161,35 @@ machine_at_acerv60n_init(const machine_t *model) return ret; } +int +machine_at_lgibm440fx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibm440fx/bios.rom", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 4, 1, 2, 3); + device_add(&i440fx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&w83787f_device); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_vs440fx_init(const machine_t *model) { diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 8e4b99b56fc..ae850eee4b3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -617,7 +617,8 @@ DEVOBJ := bugger.o cartridge.o cassette.o hasp.o hwm.o hwm_lm75.o hwm_lm78.o hwm mouse_bus.o \ mouse_serial.o mouse_ps2.o \ mouse_wacom_tablet.o \ - phoenix_486_jumper.o serial_passthrough.o + nec_mate_unk.o phoenix_486_jumper.o \ + serial_passthrough.o SIOOBJ := sio_acc3221.o sio_ali5123.o \ sio_f82c710.o sio_82091aa.o sio_fdc37c6xx.o \ From 6139c14245875bd0d25bc5550921f17d8f8c3210 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:13:35 +0100 Subject: [PATCH 105/146] And chipset.h. --- src/include/86box/chipset.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 95440a1723b..4aa3ee3e9b8 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -174,6 +174,8 @@ extern const device_t vlsi_scamp_device; extern const device_t wd76c10_device; /* Miscellaneous Hardware */ +extern const device_t nec_mate_unk_device; + extern const device_t phoenix_486_jumper_device; extern const device_t phoenix_486_jumper_pci_device; From dbb53ce21a37d62e8319670749c3de7f0035efb1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:27:35 +0100 Subject: [PATCH 106/146] Finishing touches. --- src/device/nec_mate_unk.c | 13 ++- src/include/86box/machine.h | 2 + src/machine/m_at_slot1.c | 57 ++++++++++-- src/machine/machine_table.c | 180 ++++++++++++++++++++++++++++++++++-- 4 files changed, 231 insertions(+), 21 deletions(-) diff --git a/src/device/nec_mate_unk.c b/src/device/nec_mate_unk.c index d49805fc88f..165962f307f 100644 --- a/src/device/nec_mate_unk.c +++ b/src/device/nec_mate_unk.c @@ -29,9 +29,6 @@ #include <86box/chipset.h> #include <86box/plat_unused.h> - if ((port == 0x6b) || (port == 0x3d6d)) - ret = 0x2a; - static uint8_t nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) { @@ -46,6 +43,8 @@ nec_mate_unk_read(UNUSED(uint16_t addr), void *priv) static void nec_mate_unk_close(void *priv) { + uint8_t *dev = (uint8_t *) priv; + free(dev); } @@ -63,12 +62,12 @@ nec_mate_unk_init(const device_t *info) const device_t nec_mate_unk_device = { .name = "NEC Mate NX MA30D/23D Unknown Readout", - .internal_name = "nec_mate_unk_jumper", + .internal_name = "nec_mate_unk", .flags = 0, .local = 0, - .init = nec_mate_unk_jumper_init, - .close = nec_mate_unk_jumper_close, - .reset = nec_mate_unk_jumper_reset, + .init = nec_mate_unk_init, + .close = nec_mate_unk_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, .force_redraw = NULL, diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d75d65a01a2..65e36959ac3 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -728,6 +728,8 @@ extern int machine_at_kn97_init(const machine_t *); extern int machine_at_lx6_init(const machine_t *); extern int machine_at_spitfire_init(const machine_t *); +extern int machine_at_mate_nx_ma30d_23d_init(const machine_t *); + extern int machine_at_p6i440e2_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 184cfc34d6e..d1e348ba490 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -152,6 +152,43 @@ machine_at_spitfire_init(const machine_t *model) return ret; } +int +machine_at_mate_nx_ma30d_23d_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/mate_nx_ma30d_23d/BIOS.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); +#ifdef UNKNOWN_SLOT + pci_register_slot(0x0A, PCI_CARD_NETWORK, 2, 3, 4, 1); /* ???? device - GPIO? */ +#endif + pci_register_slot(0x14, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 3, 0, 0, 0); + device_add(&i440lx_device); + device_add(&piix4e_device); + device_add(&nec_mate_unk_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&fdc37c67x_device); + device_add(&intel_flash_bxt_device); + spd_register(SPD_TYPE_SDRAM, 0xF, 256); + device_add(&lm78_device); /* no reporting in BIOS */ + + return ret; +} + int machine_at_p6i440e2_init(const machine_t *model) { @@ -199,13 +236,21 @@ machine_at_p2bls_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); - pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); + // pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + // pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); + // pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); +#if 0 pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 4, 1, 2); +#else + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x14, PCI_CARD_NORMAL, 4, 1, 2, 3); +#endif pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); device_add(&i440bx_device); device_add(&piix4e_device); @@ -216,9 +261,9 @@ machine_at_p2bls_init(const machine_t *model) #endif device_add(&sst_flash_39sf020_device); spd_register(SPD_TYPE_SDRAM, 0xF, 256); - device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ - hwm_values.temperatures[1] = 0; /* unused */ - hwm_values.temperatures[2] -= 3; /* CPU offset */ + // device_add(&w83781d_device); /* fans: Chassis, CPU, Power; temperatures: MB, unused, CPU */ + // hwm_values.temperatures[1] = 0; /* unused */ + // hwm_values.temperatures[2] -= 3; /* CPU offset */ return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 014417426d0..3a260d9ae73 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9524,6 +9524,48 @@ const machine_t machines[] = { }, /* 430VX */ + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { + .name = "[i430VX] Dell Hannibal+", + .internal_name = "dell_430vx", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430VX, + .init = machine_at_dell_430vx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has AMIKey H KBC firmware (AMIKey-2). */ { .name = "[i430VX] ECS P5VX-B", @@ -11614,6 +11656,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* It's a Intel VS440FX with a Gateway 2000 OEM BIOS */ + { + .name = "[i440FX] Gateway 2000 Venus", + .internal_name = "gw2kvenus", + .type = MACHINE_TYPE_SOCKET8, + .chipset = MACHINE_CHIPSET_INTEL_440FX, + .init = machine_at_gw2kvenus_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET8, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 2.0, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { .name = "[i440FX] Gigabyte GA-686NX", .internal_name = "686nx", @@ -11737,13 +11820,13 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* It's a Intel VS440FX with a Gateway 2000 OEM BIOS */ + /* Has the AMIKey-2 (updated 'H') KBC firmware. */ { - .name = "[i440FX] Gateway 2000 Venus", - .internal_name = "gw2kvenus", + .name = "[i440FX] LG IBM Multinet x61 (MSI MS-6106)", + .internal_name = "lgibm440fx", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, - .init = machine_at_gw2kvenus_init, + .init = machine_at_lgibm440fx_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -11753,15 +11836,15 @@ const machine_t machines[] = { .block = CPU_BLOCK_NONE, .min_bus = 60000000, .max_bus = 66666667, - .min_voltage = 2100, + .min_voltage = 2500, .max_voltage = 3500, - .min_multi = 2.0, - .max_multi = 3.5 + .min_multi = 1.5, + .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_PCI, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, .ram = { - .min = 8192, + .min = 40960, .max = 524288, .step = 8192 }, @@ -12069,6 +12152,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with Phoenix or + AMIKey-2 KBC firmware. */ + { + .name = "[i440LX] NEC Mate NX MA30D/23D", + .internal_name = "mate_nx_ma30d_23d", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440LX, + .init = machine_at_mate_nx_ma30d_23d_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 66666667, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 440EX */ /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC @@ -13037,6 +13161,46 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Mitsubishi 38813 with AMIKey-3 KBC firmware. */ + { + .name = "[i440BX] NEC LaVie C PC-LC500J34DR", + .internal_name = "lc500j34dr", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_lc500j34dr_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 133333333, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 /* limits assumed */ + }, + .bus_flags = MACHINE_PS2_AGP, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From 24993bca73b2c33c70c43ba8660bbbb6f904b91a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 28 Dec 2023 22:29:19 +0100 Subject: [PATCH 107/146] Removed the leftovers of the locally added LC500J machine. --- src/include/86box/machine.h | 1 - src/machine/machine_table.c | 40 ------------------------------------- 2 files changed, 41 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 65e36959ac3..ddbce0ae486 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -763,7 +763,6 @@ extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_m773_init(const machine_t *); extern int machine_at_ambx133_init(const machine_t *); extern int machine_at_awo671r_init(const machine_t *); -extern int machine_at_lc500j34dr_init(const machine_t *); extern int machine_at_63a1_init(const machine_t *); extern int machine_at_s370sba_init(const machine_t *); extern int machine_at_apas3_init(const machine_t *); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3a260d9ae73..54b9258f444 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -13161,46 +13161,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a Mitsubishi 38813 with AMIKey-3 KBC firmware. */ - { - .name = "[i440BX] NEC LaVie C PC-LC500J34DR", - .internal_name = "lc500j34dr", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_lc500j34dr_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET370, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 133333333, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 /* limits assumed */ - }, - .bus_flags = MACHINE_PS2_AGP, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 255, - .kbc_device = NULL, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From 8ba35218faf4097fc35e4c8df9a6f008c269730f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 12:24:20 +0600 Subject: [PATCH 108/146] Millennium II: Fix squished image on MGA modes --- src/video/vid_mga.c | 86 +++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 96b1d75edf7..d8ca5a6a7d8 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -736,17 +736,22 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) case 0x3df: if (mystique->crtcext_idx == 1) svga->dpms = !!(val & 0x30); + old = mystique->crtcext_regs[mystique->crtcext_idx]; if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; + + if (mystique->crtcext_idx == 6 && (old ^ val) == CRTCX_R3_MGAMODE && mystique->type >= MGA_2164W) + svga_recalctimings(svga); if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->rowoffset <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->rowoffset <<= 1; svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { svga->rowoffset <<= 1; svga->ma_latch <<= 1; } @@ -935,7 +940,7 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { svga->rowoffset <<= 1; if (mystique->type >= MGA_1064SG) svga->ma_latch <<= 1; @@ -957,34 +962,55 @@ mystique_recalctimings(svga_t *svga) mystique->ma_latch_old = svga->ma_latch; } - svga->rowoffset <<= 1; - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { - case XMULCTRL_DEPTH_8: - case XMULCTRL_DEPTH_2G8V16: - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case XMULCTRL_DEPTH_15: - case XMULCTRL_DEPTH_G16V16: - svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - break; - case XMULCTRL_DEPTH_16: - svga->render = svga_render_16bpp_highres; - svga->bpp = 16; - break; - case XMULCTRL_DEPTH_24: - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case XMULCTRL_DEPTH_32: - case XMULCTRL_DEPTH_32_OVERLAYED: - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; + if (!(mystique->type >= MGA_2164W)) + svga->rowoffset <<= 1; + if (mystique->type != MGA_2164W) { + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; - default: - break; + default: + break; + } + } else { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } } } else { switch (svga->bpp) { From d1af2fe85dce8fec1732c653c721d6d9487670fe Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 13:19:46 +0600 Subject: [PATCH 109/146] Millennnium II now working --- src/video/vid_mga.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d8ca5a6a7d8..33be96fa6db 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -756,7 +756,8 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) svga->ma_latch <<= 1; } - svga->ma_latch <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->ma_latch <<= 1; if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + @@ -949,7 +950,8 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) { /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ - svga->ma_latch <<= 1; + if (!(mystique->type >= MGA_2164W)) + svga->ma_latch <<= 1; /* Only change maback so the new display start will take effect on the next horizontal retrace. */ if (svga->ma_latch != mystique->ma_latch_old) { @@ -1009,6 +1011,7 @@ mystique_recalctimings(svga_t *svga) break; case 32: svga->render = svga_render_32bpp_highres; + svga->rowoffset <<= 1; break; } } @@ -1714,6 +1717,7 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_MACCESS + 3: WRITE8(addr, mystique->maccess, val); mystique->dwgreg.dither = mystique->maccess >> 30; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_MCTLWTST: @@ -2575,6 +2579,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_PRIMEND: thread_wait_mutex(mystique->dma.lock); mystique->dma.primend = val; + //pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend); if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 0; mystique->status &= ~STATUS_ENDPRDMASTS; @@ -5074,6 +5079,7 @@ blit_bitblt(mystique_t *mystique) case DWGCTRL_ATYPE_BLK: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: src_addr = mystique->dwgreg.ar[3]; for (y = 0; y < mystique->dwgreg.length; y++) { @@ -5082,7 +5088,7 @@ blit_bitblt(mystique_t *mystique) while (1) { if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7); uint32_t old_dst; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { @@ -5180,6 +5186,7 @@ blit_bitblt(mystique_t *mystique) case DWGCTRL_ATYPE_RSTR: switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); @@ -5191,7 +5198,7 @@ blit_bitblt(mystique_t *mystique) while (1) { uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + int bit_offset = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF) ? (7 - (src_addr & 7)) : (src_addr & 7); if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; From 592229af947eb90861f4c13dae3f296f24462154 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 14:59:09 +0600 Subject: [PATCH 110/146] 1. 16MB option 2. rowoffset fixes --- src/video/vid_mga.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33be96fa6db..d5ee42b30ad 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -772,12 +772,22 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx == 4) { if (svga->gdcreg[6] & 0xc) { /*64k banks*/ - svga->read_bank = (val & 0x7f) << 16; - svga->write_bank = (val & 0x7f) << 16; + if (mystique->type >= MGA_2164W) { + svga->read_bank = val << 16; + svga->write_bank = val << 16; + } else { + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } } else { /*128k banks*/ - svga->read_bank = (val & 0x7e) << 16; - svga->write_bank = (val & 0x7e) << 16; + if (mystique->type >= MGA_2164W) { + svga->read_bank = (val & 0xfe) << 16; + svga->write_bank = (val & 0xfe) << 16; + } else { + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } } } break; @@ -1005,9 +1015,13 @@ mystique_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; + if (svga->hdisp >= 1024) + svga->rowoffset <<= 1; break; case 24: svga->render = svga_render_24bpp_highres; + if (svga->hdisp >= 1024) + svga->rowoffset <<= 1; break; case 32: svga->render = svga_render_32bpp_highres; @@ -6016,7 +6030,7 @@ mystique_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); if (mystique->type == MGA_2064W || mystique->type == MGA_2164W) { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, (mystique->type == MGA_2164W) ? &timing_matrox_mystique : &timing_matrox_millennium); svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, mystique_recalctimings, mystique_in, mystique_out, @@ -6026,6 +6040,8 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + if (mystique->vram_size >= 16) + mystique->svga.decode_mask = mystique->svga.vram_mask; tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); } else { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); @@ -6230,6 +6246,10 @@ static const device_config_t millennium_ii_config[] = { .description = "8 MB", .value = 8 }, + { + .description = "16 MB", + .value = 16 + }, { .description = "" } @@ -6295,5 +6315,5 @@ const device_t millennium_ii_device = { { .available = millennium_ii_available }, .speed_changed = mystique_speed_changed, .force_redraw = mystique_force_redraw, - .config = mystique_config + .config = millennium_ii_config }; From a037b7618e8a52cba45c4e5bae00f1931ed59ad1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 29 Dec 2023 15:45:26 +0600 Subject: [PATCH 111/146] MGA: Fix most remaining display problems with Millennium II --- src/video/vid_mga.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d5ee42b30ad..2f524db5da1 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -740,15 +740,14 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (mystique->crtcext_idx < 6) mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 6 && (old ^ val) == CRTCX_R3_MGAMODE && mystique->type >= MGA_2164W) - svga_recalctimings(svga); - if ((mystique->type >= MGA_1064SG) && (mystique->crtcext_idx == 0) && (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE)) { svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + if (!(mystique->type >= MGA_2164W)) svga->rowoffset <<= 1; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { @@ -758,6 +757,36 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) if (!(mystique->type >= MGA_2164W)) svga->ma_latch <<= 1; + + if (mystique->type == MGA_2164W) + { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + if (svga->dispend >= 1024) + svga->rowoffset <<= 1; + break; + case 24: + svga->render = svga_render_24bpp_highres; + if (svga->hdisp >= 1024) + svga->rowoffset <<= 1; + break; + case 32: + svga->render = svga_render_32bpp_highres; + svga->rowoffset <<= 1; + if (svga->hdisp >= 1024) { + svga->ma_latch <<= 1; + } + break; + } + } + if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + @@ -1015,7 +1044,7 @@ mystique_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; - if (svga->hdisp >= 1024) + if (svga->dispend >= 1024) svga->rowoffset <<= 1; break; case 24: @@ -1026,6 +1055,9 @@ mystique_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; svga->rowoffset <<= 1; + if (svga->hdisp >= 1024) { + svga->ma_latch <<= 1; + } break; } } From f13a4a5723907ec6045fdc35e94b45827fcccb31 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 29 Dec 2023 11:10:15 +0100 Subject: [PATCH 112/146] PIIX3: Fixed USB legacy support register masks. --- src/chipset/intel_piix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 2094eefcfe4..70035f6dfd1 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1006,11 +1006,11 @@ piix_write(int func, int addr, uint8_t val, void *priv) break; case 0xc0: if (dev->type <= 4) - fregs[0xc0] = (fregs[0xc0] & ~(val & 0xbf)) | (val & 0x20); + fregs[0xc0] = (fregs[0xc0] & 0x40) | (val & 0xbf); break; case 0xc1: if (dev->type <= 4) - fregs[0xc1] &= ~val; + fregs[0xc1] = (fregs[0xc0] & ~(val & 0x8f)) | (val & 0x20); break; case 0xff: if (dev->type == 4) { From b93b6d6f2beb5f92e2051319410a467d22e9ec5f Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 29 Dec 2023 11:12:45 +0100 Subject: [PATCH 113/146] Added the Cardex S3 Trio64V+. --- src/include/86box/video.h | 1 + src/video/vid_s3.c | 37 +++++++++++++++++++++++++++++++++++-- src/video/vid_table.c | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 3d1339f3b79..61881976877 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -487,6 +487,7 @@ extern const device_t s3_phoenix_trio64_onboard_pci_device; extern const device_t s3_phoenix_trio64_pci_device; extern const device_t s3_phoenix_trio64vplus_pci_device; extern const device_t s3_phoenix_trio64vplus_onboard_pci_device; +extern const device_t s3_cardex_trio64vplus_pci_device; extern const device_t s3_mirocrystal_20sv_964_vlb_device; extern const device_t s3_mirocrystal_20sv_964_pci_device; extern const device_t s3_mirocrystal_20sd_864_vlb_device; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 9a56acdd7db..94c251927a6 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -62,6 +62,7 @@ #define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" #define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" #define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" +#define ROM_CARDEX_TRIO64VPLUS "roms/video/s3/S3T64VP.VBI" #define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" #define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" #define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" @@ -92,6 +93,7 @@ enum { S3_TRIO64V2_DX_ONBOARD, S3_PHOENIX_TRIO64VPLUS, S3_PHOENIX_TRIO64VPLUS_ONBOARD, + S3_CARDEX_TRIO64VPLUS, S3_DIAMOND_STEALTH_SE, S3_DIAMOND_STEALTH_VRAM, S3_ELSAWIN2KPROX_964, @@ -146,6 +148,7 @@ static video_timings_t timing_s3_trio32_vlb = { .type = VIDEO_BUS, .write_b = static video_timings_t timing_s3_trio32_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 3, .write_l = 5, .read_b = 26, .read_w = 26, .read_l = 42 }; static video_timings_t timing_s3_trio64_vlb = { .type = VIDEO_BUS, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; static video_timings_t timing_s3_trio64_pci = { .type = VIDEO_PCI, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; +static video_timings_t timing_s3_trio64vp_cardex_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 19, .read_w = 19, .read_l = 30 }; enum { VRAM_4MB = 0, @@ -2894,7 +2897,8 @@ s3_in(uint16_t addr, void *priv) temp = svga->seqregs[svga->seqaddr]; /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not get stuck in an infinite loop. */ - if ((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) && (svga->seqaddr == 0x17)) + if (((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) || + (s3->card_type == S3_CARDEX_TRIO64VPLUS)) && (svga->seqaddr == 0x17)) svga->seqregs[svga->seqaddr] ^= 0x01; return temp; } @@ -7891,12 +7895,15 @@ s3_reset(void *priv) case S3_PHOENIX_TRIO64: case S3_PHOENIX_TRIO64_ONBOARD: + case S3_CARDEX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: case S3_NUMBER9_9FX: - if (s3->card_type == S3_PHOENIX_TRIO64VPLUS || s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) + if ((s3->card_type == S3_CARDEX_TRIO64VPLUS) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS) || + (s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD)) svga->crtc[0x53] = 0x08; break; @@ -8141,6 +8148,11 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); break; + case S3_CARDEX_TRIO64VPLUS: + bios_fn = ROM_CARDEX_TRIO64VPLUS; + chip = S3_TRIO64V; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64vp_cardex_pci); + break; case S3_DIAMOND_STEALTH64_764: bios_fn = ROM_DIAMOND_STEALTH64_764; chip = S3_TRIO64; @@ -8543,6 +8555,7 @@ s3_init(const device_t *info) case S3_PHOENIX_TRIO64_ONBOARD: case S3_PHOENIX_TRIO64VPLUS: case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + case S3_CARDEX_TRIO64VPLUS: case S3_DIAMOND_STEALTH64_764: case S3_SPEA_MIRAGE_P64: if (device_get_config_int("memory") == 1) @@ -8786,6 +8799,12 @@ s3_phoenix_trio64vplus_available(void) return rom_present(ROM_PHOENIX_TRIO64VPLUS); } +static int +s3_cardex_trio64vplus_available(void) +{ + return rom_present(ROM_PHOENIX_TRIO64VPLUS); +} + static int s3_diamond_stealth64_764_available(void) { @@ -9417,6 +9436,20 @@ const device_t s3_phoenix_trio64vplus_pci_device = { .config = s3_standard_config }; +const device_t s3_cardex_trio64vplus_pci_device = { + .name = "S3 Trio64V+ PCI (Cardex)", + .internal_name = "cardex_trio64vplus_pci", + .flags = DEVICE_PCI, + .local = S3_CARDEX_TRIO64VPLUS, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + { .available = s3_cardex_trio64vplus_available }, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_phoenix_vision864_vlb_device = { .name = "S3 Vision864 VLB (Phoenix)", .internal_name = "px_vision864_vlb", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 0532a15a805..37e399d222d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -192,6 +192,7 @@ video_cards[] = { { &s3_spea_mercury_p64v_pci_device }, { &s3_9fx_531_pci_device }, { &s3_phoenix_vision868_pci_device }, + { &s3_cardex_trio64vplus_pci_device }, { &s3_phoenix_trio64vplus_pci_device }, { &s3_trio64v2_dx_pci_device }, { &s3_virge_325_pci_device }, From 5663f9aa3b9d544bfaa37958a474bcbb9b56d813 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 01:20:19 +0600 Subject: [PATCH 114/146] Millennium II: Don't ignore OPTION_INTERLEAVE Cleanups --- src/video/vid_mga.c | 43 +++---------------------------------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 2f524db5da1..6e85cfe5ea0 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -750,42 +750,13 @@ mystique_out(uint16_t addr, uint8_t val, void *priv) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; svga->ma_latch <<= 1; } if (!(mystique->type >= MGA_2164W)) svga->ma_latch <<= 1; - - if (mystique->type == MGA_2164W) - { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - if (svga->dispend >= 1024) - svga->rowoffset <<= 1; - break; - case 24: - svga->render = svga_render_24bpp_highres; - if (svga->hdisp >= 1024) - svga->rowoffset <<= 1; - break; - case 32: - svga->render = svga_render_32bpp_highres; - svga->rowoffset <<= 1; - if (svga->hdisp >= 1024) { - svga->ma_latch <<= 1; - } - break; - } - } if (svga->ma_latch != mystique->ma_latch_old) { if (svga->interlace && svga->oddeven) @@ -980,14 +951,14 @@ mystique_recalctimings(svga_t *svga) if (mystique->type >= MGA_1064SG) svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) && !(mystique->type >= MGA_2164W)) { + if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; if (mystique->type >= MGA_1064SG) svga->ma_latch <<= 1; } if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take + /*Mystique and later, unlike most SVGA cards, allows display start to take effect mid-screen*/ if (!(mystique->type >= MGA_2164W)) svga->ma_latch <<= 1; @@ -1044,20 +1015,12 @@ mystique_recalctimings(svga_t *svga) break; case 16: svga->render = svga_render_16bpp_highres; - if (svga->dispend >= 1024) - svga->rowoffset <<= 1; break; case 24: svga->render = svga_render_24bpp_highres; - if (svga->hdisp >= 1024) - svga->rowoffset <<= 1; break; case 32: svga->render = svga_render_32bpp_highres; - svga->rowoffset <<= 1; - if (svga->hdisp >= 1024) { - svga->ma_latch <<= 1; - } break; } } From 148e466b807bb547a49891c6d691f98854157aeb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 01:27:04 +0600 Subject: [PATCH 115/146] Implement BAR swap for Matrox Mystique 220 Revision ID now properly indicates a Mystique 220 card --- src/video/vid_mga.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 6e85cfe5ea0..66a7dca71d6 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5676,9 +5676,9 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; - if (mystique->type >= MGA_2164W) + if (mystique->type >= MGA_1164SG) { - /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ if (addr >= 0x10 && addr <= 0x13) addr += 0x4; else if (addr >= 0x14 && addr <= 0x17) @@ -5718,7 +5718,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; /*Fast DEVSEL timing*/ case 0x08: - ret = 0; + ret = (mystique->type == MGA_1164SG) ? 3 : 0; break; /*Revision ID*/ case 0x09: ret = 0; @@ -5837,9 +5837,9 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; - if (mystique->type >= MGA_2164W) + if (mystique->type >= MGA_1164SG) { - /* Millennium II and later Matrox cards swap MGABASE1 and 2. */ + /* Mystique 220, Millennium II and later Matrox cards swap MGABASE1 and 2. */ if (addr >= 0x10 && addr <= 0x13) addr += 0x4; else if (addr >= 0x14 && addr <= 0x17) From 4d7fd68bbc5440d5bfb6f234e9afe7e9ec46b8e4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 02:10:45 +0600 Subject: [PATCH 116/146] Millennium and Millennium 2: Enable gamma correction only for 24+ bpp TVP3026 datasheet poorly or doesn't document at all gamma correction for 15/16 bpp --- src/video/vid_mga.c | 7 +++++-- src/video/vid_tvp3026_ramdac.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 66a7dca71d6..d30b2d681f0 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -947,9 +947,12 @@ mystique_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) << 3; svga->hdisp_time = svga->hdisp; svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); + + if (mystique->type != MGA_2164W && mystique->type != MGA_2064W) + svga->lut_map = !!(mystique->xmiscctrl & XMISCCTRL_RAMCS); + if (mystique->type >= MGA_1064SG) - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; if ((mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8))) { svga->rowoffset <<= 1; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 611527a358d..008f89a8bb0 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -515,6 +515,8 @@ tvp3026_recalctimings(void *priv, svga_t *svga) const tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; svga->interlace = (ramdac->ccr & 0x40); + /* TODO: Figure out gamma correction for 15/16 bpp color. */ + svga->lut_map = !!(svga->bpp >= 24 && (ramdac->true_color & 0xf0) != 0x00); } void From dddf46f28a969d9ca38f19e4ec54dbee6e7652cf Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 02:31:56 +0600 Subject: [PATCH 117/146] TVP3026: Implement gamma correction for 15/16 bpp modes --- src/include/86box/vid_svga.h | 13 +++++++------ src/video/vid_mga.c | 5 ++++- src/video/vid_s3.c | 7 ++++--- src/video/vid_tvp3026_ramdac.c | 26 +++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 4d553900507..7ba637167aa 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -404,12 +404,13 @@ extern float stg_getclock(int clock, void *priv); extern void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t tkd8001_ramdac_in(uint16_t addr, void *priv, svga_t *svga); -extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); -extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); -extern void tvp3026_recalctimings(void *priv, svga_t *svga); -extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); -extern float tvp3026_getclock(int clock, void *priv); -extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); +extern void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_t *svga); +extern uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga); +extern uint32_t tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp); +extern void tvp3026_recalctimings(void *priv, svga_t *svga); +extern void tvp3026_hwcursor_draw(svga_t *svga, int displine); +extern float tvp3026_getclock(int clock, void *priv); +extern void tvp3026_gpio(uint8_t (*read)(uint8_t cntl, void *priv), void (*write)(uint8_t cntl, uint8_t data, void *priv), void *cb_priv, void *priv); # ifdef EMU_DEVICE_H extern const device_t ati68860_ramdac_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index d30b2d681f0..521c561df17 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6038,6 +6038,7 @@ mystique_init(const device_t *info) mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); mystique->svga.clock_gen = mystique->svga.ramdac; mystique->svga.getclock = tvp3026_getclock; + mystique->svga.conv_16to32 = tvp3026_conv_16to32; if (mystique->vram_size >= 16) mystique->svga.decode_mask = mystique->svga.vram_mask; tvp3026_gpio(mystique_tvp3026_gpio_read, mystique_tvp3026_gpio_write, mystique, mystique->svga.ramdac); @@ -6126,7 +6127,9 @@ mystique_init(const device_t *info) mystique->softrap_status_read = 1; mystique->svga.vsync_callback = mystique_vsync_callback; - mystique->svga.conv_16to32 = mystique_conv_16to32; + + if (mystique->type != MGA_2064W && mystique->type != MGA_2164W) + mystique->svga.conv_16to32 = mystique_conv_16to32; mystique->i2c = i2c_gpio_init("i2c_mga"); mystique->i2c_ddc = i2c_gpio_init("ddc_mga"); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 9a56acdd7db..3c11b90ee1a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -8491,9 +8491,10 @@ s3_init(const device_t *info) svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; } else { - svga->ramdac = device_add(&tvp3026_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = tvp3026_getclock; + svga->ramdac = device_add(&tvp3026_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = tvp3026_getclock; + svga->conv_16to32 = tvp3026_conv_16to32; } break; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 008f89a8bb0..2de3117b95a 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -516,7 +516,31 @@ tvp3026_recalctimings(void *priv, svga_t *svga) svga->interlace = (ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ - svga->lut_map = !!(svga->bpp >= 24 && (ramdac->true_color & 0xf0) != 0x00); + svga->lut_map = !!(svga->bpp >= 15 && (ramdac->true_color & 0xf0) != 0x00); +} + +uint32_t +tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t*)svga->ramdac; + uint32_t ret = 0x00000000; + + if (svga->lut_map) { + if (bpp == 15) { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x3e0) >> 2]); + uint8_t r = getcolb(svga->pallook[(color & 0x7c00) >> 7]); + ret = (video_15to32[color] & 0xFF000000) | makecol(r, g, b); + } else { + uint8_t b = getcolr(svga->pallook[(color & 0x1f) << 3]); + uint8_t g = getcolg(svga->pallook[(color & 0x7e0) >> 3]); + uint8_t r = getcolb(svga->pallook[(color & 0xf800) >> 8]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } + } else + ret = (bpp == 15) ? video_15to32[color] : video_16to32[color]; + + return ret; } void From 7701174b39ddd4eb20d1121a8d2dbfa9bcb7451b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Dec 2023 00:04:57 +0100 Subject: [PATCH 118/146] CL-GD 5446/5480: Implement missing byte swap behavior, fixes fonts with the Windows 3.1 CL-GD 5446 driver when cache is enabled. --- src/video/vid_cl54xx.c | 146 +++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 56 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 05e45b7d7fe..c6b3b725f46 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -2074,18 +2074,49 @@ gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) } static uint8_t -gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) +gd54xx_get_aperture(uint32_t addr) +{ + uint32_t ap = addr >> 22; + return (uint8_t) (ap & 0x03); +} + +static uint32_t +gd54xx_mem_sys_pos_adj(gd54xx_t *gd54xx, uint8_t ap, uint32_t pos) { + uint32_t ret = pos; + + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + switch (ap) { + case 1: + ret ^= 1; + break; + case 2: + ret ^= 3; + break; + } + } + + return ret; +} + +static uint8_t +gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx, uint8_t ap) +{ + uint32_t adj_pos = gd54xx_mem_sys_pos_adj(gd54xx, ap, gd54xx->blt.msd_buf_pos); uint8_t ret = 0xff; if (gd54xx->blt.msd_buf_cnt != 0) { - ret = gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos++]; + ret = gd54xx->blt.msd_buf[adj_pos]; + + gd54xx->blt.msd_buf_pos++; gd54xx->blt.msd_buf_cnt--; if (gd54xx->blt.msd_buf_cnt == 0) { if (gd54xx->countminusone == 1) { gd54xx->blt.msd_buf_pos = 0; - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) gd54xx_start_blit(0xff, 8, gd54xx, &gd54xx->svga); else gd54xx_start_blit(0xffffffff, 32, gd54xx, &gd54xx->svga); @@ -2098,14 +2129,17 @@ gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) } static void -gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val) +gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val, uint8_t ap) { - gd54xx->blt.sys_src32 &= ~(0xff << (gd54xx->blt.sys_cnt << 3)); - gd54xx->blt.sys_src32 |= (val << (gd54xx->blt.sys_cnt << 3)); + uint32_t adj_pos = gd54xx_mem_sys_pos_adj(gd54xx, ap, gd54xx->blt.sys_cnt); + + gd54xx->blt.sys_src32 &= ~(0xff << (adj_pos << 3)); + gd54xx->blt.sys_src32 |= (val << (adj_pos << 3)); gd54xx->blt.sys_cnt = (gd54xx->blt.sys_cnt + 1) & 3; if (gd54xx->blt.sys_cnt == 0) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && + !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { for (uint8_t i = 0; i < 32; i += 8) gd54xx_start_blit((gd54xx->blt.sys_src32 >> i) & 0xff, 8, gd54xx, &gd54xx->svga); } else @@ -2120,7 +2154,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) svga_t *svga = &gd54xx->svga; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } @@ -2251,13 +2285,6 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) svga->changedvram[addr >> 12] = changeframecount; } -static uint8_t -gd54xx_get_aperture(uint32_t addr) -{ - uint32_t ap = addr >> 22; - return (uint8_t) (ap & 0x03); -} - static int gd54xx_aperture2_enabled(gd54xx_t *gd54xx) { @@ -2294,7 +2321,7 @@ gd54xx_readb_linear(uint32_t addr, void *priv) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + return gd54xx_mem_sys_dest_read(gd54xx, ap); switch (ap) { default: @@ -2318,8 +2345,9 @@ gd54xx_readb_linear(uint32_t addr, void *priv) static uint16_t gd54xx_readw_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); uint16_t temp; @@ -2338,8 +2366,8 @@ gd54xx_readw_linear(uint32_t addr, void *priv) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, priv); - temp |= gd54xx_readb_linear(addr + 1, priv) << 8; + temp = gd54xx_readb_linear(old_addr, priv); + temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; return temp; } @@ -2367,8 +2395,9 @@ gd54xx_readw_linear(uint32_t addr, void *priv) static uint32_t gd54xx_readl_linear(uint32_t addr, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; uint8_t ap = gd54xx_get_aperture(addr); uint32_t temp; @@ -2387,10 +2416,10 @@ gd54xx_readl_linear(uint32_t addr, void *priv) /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, priv); - temp |= gd54xx_readb_linear(addr + 1, priv) << 8; - temp |= gd54xx_readb_linear(addr + 2, priv) << 16; - temp |= gd54xx_readb_linear(addr + 3, priv) << 24; + temp = gd54xx_readb_linear(old_addr, priv); + temp |= gd54xx_readb_linear(old_addr + 1, priv) << 8; + temp |= gd54xx_readb_linear(old_addr + 2, priv) << 16; + temp |= gd54xx_readb_linear(old_addr + 3, priv) << 24; return temp; } @@ -2427,9 +2456,11 @@ static uint8_t gd5436_aperture2_readb(UNUSED(uint32_t addr), void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; + uint8_t ap = gd54xx_get_aperture(addr); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + return gd54xx_mem_sys_dest_read(gd54xx, ap); return 0xff; } @@ -2440,7 +2471,8 @@ gd5436_aperture2_readw(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; uint16_t ret = 0xffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd5436_aperture2_readb(addr, priv); ret |= gd5436_aperture2_readb(addr + 1, priv) << 8; return ret; @@ -2455,7 +2487,8 @@ gd5436_aperture2_readl(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; uint32_t ret = 0xffffffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd5436_aperture2_readb(addr, priv); ret |= gd5436_aperture2_readb(addr + 1, priv) << 8; ret |= gd5436_aperture2_readb(addr + 2, priv) << 16; @@ -2470,10 +2503,11 @@ static void gd5436_aperture2_writeb(UNUSED(uint32_t addr), uint8_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; + uint8_t ap = gd54xx_get_aperture(addr); - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - gd54xx_mem_sys_src_write(gd54xx, val); + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + gd54xx_mem_sys_src_write(gd54xx, val, ap); } static void @@ -2481,8 +2515,8 @@ gd5436_aperture2_writew(uint32_t addr, uint16_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd5436_aperture2_writeb(addr, val, gd54xx); gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); } @@ -2493,8 +2527,8 @@ gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && + gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { gd5436_aperture2_writeb(addr, val, gd54xx); gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); gd5436_aperture2_writeb(addr + 2, val >> 16, gd54xx); @@ -2508,7 +2542,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) priv; svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { svga_write_linear(addr, val, svga); @@ -2526,7 +2560,7 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, ap); return; } @@ -2552,10 +2586,10 @@ gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *priv) static void gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; - - uint8_t ap = gd54xx_get_aperture(addr); + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; + uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { svga_writew_linear(addr, val, svga); @@ -2573,8 +2607,8 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(old_addr, val, gd54xx); + gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); return; } @@ -2619,10 +2653,10 @@ gd54xx_writew_linear(uint32_t addr, uint16_t val, void *priv) static void gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) { - gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; - - uint8_t ap = gd54xx_get_aperture(addr); + gd54xx_t *gd54xx = (gd54xx_t *) priv; + svga_t *svga = &gd54xx->svga; + uint32_t old_addr = addr; + uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { svga_writel_linear(addr, val, svga); @@ -2640,10 +2674,10 @@ gd54xx_writel_linear(uint32_t addr, uint32_t val, void *priv) /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); - gd54xx_writeb_linear(addr + 2, val >> 16, gd54xx); - gd54xx_writeb_linear(addr + 3, val >> 24, gd54xx); + gd54xx_writeb_linear(old_addr, val, gd54xx); + gd54xx_writeb_linear(old_addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(old_addr + 2, val >> 16, gd54xx); + gd54xx_writeb_linear(old_addr + 3, val >> 24, gd54xx); return; } @@ -2705,7 +2739,7 @@ gd54xx_read(uint32_t addr, void *priv) return svga_read(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + return gd54xx_mem_sys_dest_read(gd54xx, 0); addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); @@ -2938,7 +2972,7 @@ gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *priv) svga_t *svga = &gd54xx->svga; if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && gd54xx->countminusone && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); + gd54xx_mem_sys_src_write(gd54xx, val, 0); return; } @@ -3127,7 +3161,7 @@ gd543x_mmio_read(uint32_t addr, void *priv) } else if (gd54xx->mmio_vram_overlap) ret = gd54xx_read(addr, gd54xx); else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_mem_sys_dest_read(gd54xx); + ret = gd54xx_mem_sys_dest_read(gd54xx, 0); } return ret; From bfee63da82b9b78fc6925c4d573a012db7137eab Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Dec 2023 00:08:44 +0100 Subject: [PATCH 119/146] Fixes a warning in the TVP3026 RAM DAC code. --- src/video/vid_tvp3026_ramdac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 2de3117b95a..a28cc2aed42 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -522,7 +522,6 @@ tvp3026_recalctimings(void *priv, svga_t *svga) uint32_t tvp3026_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t*)svga->ramdac; uint32_t ret = 0x00000000; if (svga->lut_map) { From 4129c99cfe36d9ba21f93bd3f372c6c0f7d21b33 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 30 Dec 2023 05:54:27 +0500 Subject: [PATCH 120/146] Actually enable gameport on init on non-PnP SB16/AWE32 --- src/sound/snd_sb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 602c1c2a77b..b2a629079e8 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2141,6 +2141,7 @@ sb_16_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); return sb; } @@ -2352,6 +2353,7 @@ sb_16_compat_init(const device_t *info) sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); return sb; } @@ -2455,6 +2457,7 @@ sb_awe32_init(UNUSED(const device_t *info)) sb->gameport = gameport_add(&gameport_pnp_device); sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); return sb; } From ddb43a78c1d8da41e57d186349fd235a46d8c40a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 12:52:21 +0600 Subject: [PATCH 121/146] vid_voodoo_banshee: Implement gamma correction for 16bpp --- src/video/vid_voodoo_banshee.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index d0fad5b95c6..23236be6f34 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -219,7 +219,9 @@ enum { #define VIDPROCCFG_INTERLACE (1 << 3) #define VIDPROCCFG_HALF_MODE (1 << 4) #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) +#define VIDPROCCFG_DESKTOP_CLUT_BYPASS (1 << 10) #define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11) +#define VIDPROCCFG_DESKTOP_CLUT_SEL (1 << 12) #define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13) #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) @@ -466,6 +468,32 @@ banshee_updatemapping(banshee_t *banshee) mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } +uint32_t +banshee_conv_16to32(svga_t* svga, uint16_t color, uint8_t bpp) +{ + banshee_t *banshee = (banshee_t *) svga->priv; + uint32_t ret = 0x00000000; + uint16_t src_b = (color & 0x1f) << 3; + uint16_t src_g = (color & 0x7e0) >> 3; + uint16_t src_r = (color & 0xf800) >> 8; + + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_CLUT_SEL) { + src_b += 256; + src_g += 256; + src_r += 256; + } + + if (svga->lut_map) { + uint8_t b = getcolr(svga->pallook[src_b]); + uint8_t g = getcolg(svga->pallook[src_g]); + uint8_t r = getcolb(svga->pallook[src_r]); + ret = (video_16to32[color] & 0xFF000000) | makecol(r, g, b); + } else + ret = video_16to32[color]; + + return ret; +} + static void banshee_render_16bpp_tiled(svga_t *svga) { @@ -489,7 +517,7 @@ banshee_render_16bpp_tiled(svga_t *svga) const uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; for (uint8_t xx = 0; xx < 64; xx++) - *p++ = video_16to32[*vram_p++]; + *p++ = banshee_conv_16to32(svga, *vram_p++, 16); drawn = 1; } else @@ -806,6 +834,7 @@ banshee_ext_outl(uint16_t addr, uint32_t val, void *priv) banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; svga->fullchange = changeframecount; + svga->lut_map = !(val & VIDPROCCFG_DESKTOP_CLUT_BYPASS) && (svga->bpp < 24); svga_recalctimings(svga); break; @@ -3190,6 +3219,8 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee"); banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc)); + banshee->svga.conv_16to32 = banshee_conv_16to32; + switch (type) { case TYPE_BANSHEE: if (has_sgram) { From 9854ccc7d2c028e92a24fab6633356a0f9aaa97a Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Dec 2023 02:39:56 -0500 Subject: [PATCH 122/146] Fix debian package build --- debian/control | 11 ++++++++--- debian/copyright | 3 ++- debian/rules | 5 ++++- debian/source/format | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/debian/control b/debian/control index 78a92bf8f32..d67f5965ba3 100644 --- a/debian/control +++ b/debian/control @@ -1,18 +1,21 @@ Source: 86box Section: otherosfs Priority: optional -Maintainer: Mariusz Kurek +Maintainer: Jasmine Iwanek Build-Depends: cmake (>= 3.21), debhelper-compat (= 13), libevdev-dev, + libfluidsynth-dev, libfreetype-dev, libopenal-dev, libqt5opengl5-dev, librtmidi-dev, libsdl2-dev, libslirp-dev, + libxkbcommon-x11-dev, ninja-build, - qttools5-dev + qttools5-dev, + qtbase5-private-dev Standards-Version: 4.6.0 Homepage: https://86box.net/ #Vcs-Browser: https://salsa.debian.org/debian/86box @@ -26,4 +29,6 @@ Depends: ${shlibs:Depends}, sse2-support [i386] Recommends: libpcap0.8-dev Description: An emulator for classic IBM PC clones -#TODO: insert long description, indented with spaces + 86Box is a low level x86 emulator that runs older operating systems and software + designed for IBM PC systems and compatibles from 1981 through + fairly recent system designs based on the PCI bus. \ No newline at end of file diff --git a/debian/copyright b/debian/copyright index 22817edc5ba..9a71df3a038 100644 --- a/debian/copyright +++ b/debian/copyright @@ -8,7 +8,8 @@ Copyright: License: GPL-2.0+ Files: debian/* -Copyright: 2022 Mariusz Kurek +Copyright: 2023 Jasmine Iwanek + 2022 Mariusz Kurek License: GPL-2.0+ License: GPL-2.0+ diff --git a/debian/rules b/debian/rules index 7b0605e724c..1ee4be4edfb 100644 --- a/debian/rules +++ b/debian/rules @@ -25,7 +25,10 @@ endif dh $@ --buildsystem cmake+ninja override_dh_auto_configure: - dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) + dh_auto_configure --buildsystem cmake+ninja -- --preset regular --toolchain $(TOOLCHAIN) -DNEW_DYNAREC=$(NDR) -B . + +override_dh_auto_build: + dh_auto_build --buildsystem cmake+ninja override_dh_auto_test: diff --git a/debian/source/format b/debian/source/format index 163aaf8d82b..89ae9db8f88 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) From fa7804e1c1c0035621ffed38e3473cf7a2a009fb Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 30 Dec 2023 03:30:44 -0500 Subject: [PATCH 123/146] Correct prior maintainer's name --- debian/copyright | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/copyright b/debian/copyright index 9a71df3a038..58c9077fa0e 100644 --- a/debian/copyright +++ b/debian/copyright @@ -9,7 +9,7 @@ License: GPL-2.0+ Files: debian/* Copyright: 2023 Jasmine Iwanek - 2022 Mariusz Kurek + 2022 Lili Kurek License: GPL-2.0+ License: GPL-2.0+ From 08428d497bab16500c6fa9996db462b7497d5bfc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 16:10:28 +0600 Subject: [PATCH 124/146] Disable 32-bit Z buffer on Mystique 220 and earlier --- src/video/vid_mga.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 521c561df17..55f9cd2434e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -1729,7 +1729,10 @@ mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_MACCESS + 3: WRITE8(addr, mystique->maccess, val); mystique->dwgreg.dither = mystique->maccess >> 30; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; + if (mystique->type < MGA_2164W) + mystique->maccess &= ~MACCESS_ZWIDTH; + else + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * ((mystique->maccess & MACCESS_ZWIDTH) ? 4 : 2) + mystique->dwgreg.zorg; break; case REG_MCTLWTST: From bdae2ace60cae45039defd12f5e69016f09a77e8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 18:03:26 +0600 Subject: [PATCH 125/146] Fix a dumb copy-paste mistake --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 55f9cd2434e..33a3385d588 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4728,10 +4728,10 @@ blit_trap(mystique_t *mystique) } if (mystique->maccess_running & MACCESS_ZWIDTH) { - mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.extended_dr[0] = z_back_32 + mystique->dwgreg.extended_dr[3]; mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; } else { - mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; From 69780ecc023174ed1574121aea518d0c5aef5e52 Mon Sep 17 00:00:00 2001 From: Conrad Kostecki Date: Sat, 30 Dec 2023 13:59:04 +0100 Subject: [PATCH 126/146] Intel Premiere/PCI ED: update bios to 1013AF2 This updates the filename to match the newer 1013AF2 BIOS. Signed-off-by: Conrad Kostecki --- src/machine/m_at_socket4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index ad6d2c99594..a32617de47a 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -290,8 +290,8 @@ machine_at_revenge_init(const machine_t *model) { int ret; - ret = bios_load_linear_combined("roms/machines/revenge/1009af2_.bio", - "roms/machines/revenge/1009af2_.bi1", + ret = bios_load_linear_combined("roms/machines/revenge/1013af2_.bio", + "roms/machines/revenge/1013af2_.bi1", 0x1c000, 128); if (bios_only || !ret) From 26c1c77758dee5baf4050a99e1d50b09e43d9af5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 30 Dec 2023 20:50:17 +0600 Subject: [PATCH 127/146] Fix yet another dumb copy-paste mistake --- src/video/vid_mga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33a3385d588..0a9df92ad1b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5024,10 +5024,10 @@ blit_texture_trap(mystique_t *mystique) } if (mystique->maccess_running & MACCESS_ZWIDTH) { - mystique->dwgreg.extended_dr[0] += z_back_32 + mystique->dwgreg.extended_dr[3]; + mystique->dwgreg.extended_dr[0] = z_back_32 + mystique->dwgreg.extended_dr[3]; mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; } else { - mystique->dwgreg.dr[0] += z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); } mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; From 0265b34384234dca2e41ef5823d9dac242e4bc6d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 30 Dec 2023 19:40:05 +0100 Subject: [PATCH 128/146] 1x CD-ROM speed is 176400 bytes per second, not 176 * 1024 bytes per second. --- src/scsi/scsi_cdrom.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index d2a6170a687..65417ebe3a7 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -990,7 +990,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) if (dev->current_cdb[0] == 0x42) dev->callback += 40.0; /* Account for seek time. */ - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; case 0xc6 ... 0xc7: @@ -1011,7 +1012,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_SONY_CDU561_18k: case CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_TEXEL_DMXX24_100: - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } @@ -1023,7 +1025,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_SONY_CDU76S_100: case CDROM_TYPE_PIONEER_DRM604X_2403: case CDROM_TYPE_TEXEL_DMXX24_100: - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } @@ -1037,7 +1040,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_TEXEL_DMXX24_100: if (dev->current_cdb[0] == 0xc2) dev->callback += 40.0; - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } @@ -1049,7 +1053,8 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case CDROM_TYPE_NEC_77_106: case CDROM_TYPE_NEC_211_100: case CDROM_TYPE_NEC_464_105: - bytes_per_second = 176.0 * 1024.0; + /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ + bytes_per_second = 176400.0; bytes_per_second *= (double) dev->drv->cur_speed; break; } From bd1a5e03b059897e55921dff4f9e520eef8c45fc Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 02:19:11 +0600 Subject: [PATCH 129/146] Somewhat-working Matrox Productiva G100 --- src/include/86box/video.h | 1 + src/video/vid_mga.c | 287 +++++++++++++++++++++++++++++++++++--- src/video/vid_table.c | 1 + 3 files changed, 270 insertions(+), 19 deletions(-) diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 61881976877..0f0a1318214 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -439,6 +439,7 @@ extern const device_t millennium_device; extern const device_t mystique_device; extern const device_t mystique_220_device; extern const device_t millennium_ii_device; +extern const device_t productiva_g100_device; /* Oak OTI-0x7 */ extern const device_t oti037c_device; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0a9df92ad1b..f064b4d341e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -41,6 +41,7 @@ #define ROM_MILLENNIUM_II "roms/video/matrox/matrox2164wpc.BIN" #define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" #define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define ROM_G100 "roms/video/matrox/productiva8mbsdr.BIN" #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -166,6 +167,14 @@ #define REG_SECADDRESS 0x2c40 #define REG_SECEND 0x2c44 #define REG_SOFTRAP 0x2c48 +#define REG_ALPHASTART 0x2c70 +#define REG_ALPHACTRL 0x2c7c +#define REG_ALPHAXINC 0x2c74 +#define REG_ALPHAYINC 0x2c78 +#define REG_FOGSTART 0x1cc4 +#define REG_FOGXINC 0x1cd4 +#define REG_FOGYINC 0x1ce4 +#define REG_FOGCOL 0x1cf4 /*Mystique only*/ #define REG_PALWTADD 0x3c00 @@ -319,6 +328,7 @@ #define MACCESS_PWIDTH_32 (2 << 0) #define MACCESS_PWIDTH_24 (3 << 0) #define MACCESS_ZWIDTH (1 << 3) +#define MACCESS_FOGEN (1 << 26) #define MACCESS_TLUTLOAD (1 << 29) #define MACCESS_NODITHER (1 << 30) #define MACCESS_DIT555 (1 << 31) @@ -359,7 +369,10 @@ #define TEXCTL_PALSEL_MASK (0xf << 4) #define TEXCTL_TPITCH_SHIFT (16) #define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_TPITCHLIN (1 << 8) +#define TEXCTL_TPITCHEXT_MASK (0x7ff << 9) #define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_AZEROEXTEND (1 << 23) #define TEXCTL_DECALCKEY (1 << 24) #define TEXCTL_TAKEY (1 << 25) #define TEXCTL_TAMASK (1 << 26) @@ -394,6 +407,7 @@ enum { MGA_1064SG, /*Mystique*/ MGA_1164SG, /*Mystique 220*/ MGA_2164W, /*Millennium II*/ + MGA_G100, /*Productiva G100*/ }; enum { @@ -494,7 +508,9 @@ typedef struct mystique_t { pitch, plnwt, ybot, ydstorg, ytop, texorg, texwidth, texheight, texctl, textrans, zorg, ydst_lin, - src_addr, z_base, iload_rem_data, highv_data; + src_addr, z_base, iload_rem_data, highv_data, + fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24, + alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24; uint32_t src[4], ar[7], dr[16], tmr[9]; @@ -2560,6 +2576,38 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->softrap_pending += 1; break; + case REG_ALPHACTRL: + mystique->dwgreg.alphactrl = val; + break; + + case REG_ALPHASTART: + mystique->dwgreg.alphastart = val; + break; + + case REG_ALPHAXINC: + mystique->dwgreg.alphaxinc = val; + break; + + case REG_ALPHAYINC: + mystique->dwgreg.alphayinc = val; + break; + + case REG_FOGCOL: + mystique->dwgreg.fogcol = val; + break; + + case REG_FOGSTART: + mystique->dwgreg.fogstart = val; + break; + + case REG_FOGXINC: + mystique->dwgreg.fogxinc = val; + break; + + case REG_FOGYINC: + mystique->dwgreg.fogyinc = val; + break; + default: mystique_accel_ctrl_write_b(addr, val & 0xff, priv); mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); @@ -4781,7 +4829,7 @@ blit_trap(mystique_t *mystique) } static int -texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) +texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) { svga_t *svga = &mystique->svga; @@ -4794,6 +4842,16 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra uint16_t src = 0; int s; int t; + int tex_pitch = 1 << tex_shift; + + *tex_a = 255; + + if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) + { + tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; + if (tex_pitch == 0) + tex_pitch = 2048; + } if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); @@ -4828,7 +4886,7 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { case TEXCTL_TEXFORMAT_TW4: - src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + src = svga->vram[(mystique->dwgreg.texorg + (((t * tex_pitch) + s) >> 1)) & mystique->vram_mask]; if (s & 1) src >>= 4; else @@ -4839,14 +4897,14 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra *atransp = 0; break; case TEXCTL_TEXFORMAT_TW8: - src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + src = svga->vram[(mystique->dwgreg.texorg + (t * tex_pitch) + s) & mystique->vram_mask]; *tex_r = mystique->lut[src].r; *tex_g = mystique->lut[src].g; *tex_b = mystique->lut[src].b; *atransp = 0; break; case TEXCTL_TEXFORMAT_TW15: - src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; *tex_r = ((src >> 10) & 0x1f) << 3; *tex_g = ((src >> 5) & 0x1f) << 3; *tex_b = (src & 0x1f) << 3; @@ -4855,8 +4913,22 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra else *atransp = 0; break; + case TEXCTL_TEXFORMAT_TW12: + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 8) & 0xf) << 3; + *tex_g = ((src >> 4) & 0xf) << 3; + *tex_b = (src & 0xf) << 3; + *tex_a = ((src >> 12) & 0xf) << 3; + if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { + *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; + } else { + uint8_t ta_mask = mystique->dwgreg.ta_mask ? 0xf : 0x0; + uint8_t ta_key = mystique->dwgreg.ta_key ? 0xf : 0x0; + *atransp = (((src >> 12) & 0xf) & ta_mask) == ta_key; + } + break; case TEXCTL_TEXFORMAT_TW16: - src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; *tex_r = (src >> 11) << 3; *tex_g = ((src >> 5) & 0x3f) << 2; *tex_b = (src & 0x1f) << 3; @@ -4903,6 +4975,8 @@ blit_texture_trap(mystique_t *mystique) uint32_t s_back = mystique->dwgreg.tmr[6]; uint32_t t_back = mystique->dwgreg.tmr[7]; uint32_t q_back = mystique->dwgreg.tmr[8]; + uint32_t a_back = mystique->dwgreg.alphastart; + uint32_t fog_back = mystique->dwgreg.fogstart; while (x_l != x_r) { if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { @@ -4921,11 +4995,15 @@ blit_texture_trap(mystique_t *mystique) int tex_r = 0; int tex_g = 0; int tex_b = 0; + int tex_a = 0; int ctransp; int atransp = 0; int i_r = 0; int i_g = 0; int i_b = 0; + int i_a = 255; + int i_fog = 0; + uint8_t final_a = 255; if (!(mystique->dwgreg.dr[4] & (1 << 23))) i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; @@ -4934,7 +5012,43 @@ blit_texture_trap(mystique_t *mystique) if (!(mystique->dwgreg.dr[12] & (1 << 23))) i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + if (mystique->type >= MGA_G100) + { + if (!(mystique->dwgreg.alphastart & (1 << 23))) + i_a = (mystique->dwgreg.alphastart >> 15) & 0xff; + else + i_a = 0; + + if (!(mystique->dwgreg.fogstart & (1 << 23))) + i_fog = (mystique->dwgreg.fogstart >> 15) & 0xff; + else + i_fog = 0; + } + + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp, &tex_a); + + if (mystique->type >= MGA_G100) + { + uint8_t alpha_sel = (mystique->dwgreg.alphactrl >> 24) & 3; + + switch (alpha_sel) + { + case 0x0: /* alpha from texture */ + final_a = tex_a; + break; + default: + case 0x1: /* interpolated alpha */ + if ((mystique->dwgreg.alphactrl & (1 << 11))) + final_a = i_a; + break; + case 0x2: /* modulated alpha */ + if (!(mystique->dwgreg.alphactrl & (1 << 11))) + final_a = tex_a; + else + final_a = ((i_a * tex_a) >> 8) & 0xFF; + break; + } + } switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { case 0: @@ -4984,6 +5098,36 @@ blit_texture_trap(mystique_t *mystique) fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); } + if (mystique->type >= MGA_G100 && (mystique->maccess_running & MACCESS_FOGEN)) + { + tex_r = (tex_r * ((255 - i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * (i_fog / 255.); + tex_g = (tex_g * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * (i_fog / 255.); + tex_b = (tex_b * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * (i_fog / 255.); + } + + if (final_a != 255) + { + if (dest32) { + uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; + uint8_t dst_b = dst_col & 0xFF; + uint8_t dst_g = (dst_col >> 8) & 0xFF; + uint8_t dst_r = (dst_col >> 16) & 0xFF; + + tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); + tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); + tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); + } else { + uint16_t dst_col = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; + uint8_t dst_b = (dst_col & 0x1f) << 3; + uint8_t dst_g = (dst_col & 0x7e0) >> 3; + uint8_t dst_r = (dst_col & 0xf800) >> 8; + + tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); + tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); + tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); + } + } + if (dest32) { ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; @@ -5021,6 +5165,10 @@ blit_texture_trap(mystique_t *mystique) mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + mystique->dwgreg.fogstart += mystique->dwgreg.fogxinc; + mystique->dwgreg.alphastart += mystique->dwgreg.alphaxinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; } if (mystique->maccess_running & MACCESS_ZWIDTH) { @@ -5030,12 +5178,16 @@ blit_texture_trap(mystique_t *mystique) mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; mystique->dwgreg.extended_dr[0] = (mystique->dwgreg.extended_dr[0] & ~0xFFFFull) | ((uint64_t)mystique->dwgreg.dr[0] << 16ull); } - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; - mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; - mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.fogstart = fog_back + mystique->dwgreg.fogyinc; + mystique->dwgreg.alphastart = a_back + mystique->dwgreg.alphayinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; @@ -5063,6 +5215,10 @@ blit_texture_trap(mystique_t *mystique) mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; + mystique->dwgreg.fogstart += dx * mystique->dwgreg.fogxinc; + mystique->dwgreg.alphastart += dx * mystique->dwgreg.alphaxinc; + mystique->dwgreg.fogstart &= 0xFFFFFF; + mystique->dwgreg.alphastart &= 0xFFFFFF; mystique->dwgreg.ydst++; mystique->dwgreg.ydst &= 0x7fffff; @@ -5703,10 +5859,16 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) break; case 0x02: - ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); + if (mystique->type == MGA_G100) + ret = 0x01; + else + ret = (mystique->type == MGA_2164W) ? 0x1b : ((mystique->type == MGA_2064W) ? 0x19 : 0x1a); break; /*MGA*/ case 0x03: - ret = 0x05; + if (mystique->type == MGA_G100) + ret = 0x10; + else + ret = 0x05; break; case PCI_REG_COMMAND: @@ -5795,6 +5957,10 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) case 0x33: ret = mystique->pci_regs[0x33]; break; + + case 0x34: + ret = mystique->type == MGA_G100 ? 0xdc : 0x00; + break; case 0x3c: ret = mystique->int_line; @@ -5831,6 +5997,59 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) ret = mystique_ctrl_read_b(addr, mystique); break; + case 0xdc: + ret = 0x01; + break; + + case 0xdd: + ret = 0xf0; + break; + + case 0xde: + ret = 0x21; + break; + + /* No support for turning off the video adapter yet. */ + case 0xe0: + ret = 0x0; + break; + + case 0xf0: + ret = 0x02; + break; + + case 0xf1: + ret = 0x00; + break; + + case 0xf2: + ret = 0x10; + break; + + case 0xf4: + ret = 0x1; + break; + + case 0xf5: + ret = 0x2; + break; + + case 0xf7: + ret = 0x1; + break; + + case 0xf8: + ret = mystique->pci_regs[0xf8] & 0x7; + break; + + case 0xf9: + ret = mystique->pci_regs[0xf9] & 0x3; + break; + + case 0xfb: + ret = mystique->pci_regs[0xfb]; + break; + default: break; } @@ -5964,6 +6183,18 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) mystique_ctrl_write_b(addr, val, mystique); break; + case 0xf8: + mystique->pci_regs[0xf8] = val & 0x7; + break; + + case 0xf9: + mystique->pci_regs[0xf9] = val & 0x3; + break; + + case 0xfb: + mystique->pci_regs[0xfb] = val; + break; + default: break; } @@ -6017,6 +6248,8 @@ mystique_init(const device_t *info) romfn = ROM_MILLENNIUM_II; else if (mystique->type == MGA_1064SG) romfn = ROM_MYSTIQUE; + else if (mystique->type == MGA_G100) + romfn = ROM_G100; else romfn = ROM_MYSTIQUE_220; @@ -6186,6 +6419,12 @@ millennium_ii_available(void) return rom_present(ROM_MILLENNIUM_II); } +static int +matrox_g100_available(void) +{ + return rom_present(ROM_G100); +} + static void mystique_speed_changed(void *priv) { @@ -6242,10 +6481,6 @@ static const device_config_t millennium_ii_config[] = { .type = CONFIG_SELECTION, .selection = { - { - .description = "4 MB", - .value = 4 - }, { .description = "8 MB", .value = 8 @@ -6321,3 +6556,17 @@ const device_t millennium_ii_device = { .force_redraw = mystique_force_redraw, .config = millennium_ii_config }; + +const device_t productiva_g100_device = { + .name = "Matrox Productiva G100", + .internal_name = "productiva_g100", + .flags = DEVICE_AGP, + .local = MGA_G100, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, + { .available = matrox_g100_available }, + .speed_changed = mystique_speed_changed, + .force_redraw = mystique_force_redraw, + .config = millennium_ii_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 37e399d222d..0b56f4d6980 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -257,6 +257,7 @@ video_cards[] = { { &s3_virge_357_agp_device }, { &s3_diamond_stealth_4000_agp_device }, { &s3_trio3d2x_agp_device }, + { &productiva_g100_device }, { &velocity_100_agp_device }, { &velocity_200_agp_device }, { &voodoo_3_1000_agp_device }, From f96e25e10831572d97daa6ed2d94144a5e9f1a83 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 31 Dec 2023 05:23:17 +0500 Subject: [PATCH 130/146] Don't set the application icon in qt_main.c on Mac Should fix it overriding the bundle's icon --- src/qt/qt_main.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 02a0026d8b4..bc95ad1d1d6 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -195,18 +195,19 @@ main(int argc, char *argv[]) SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif -#ifdef RELEASE_BUILD +#ifndef Q_OS_APPLE +# ifdef RELEASE_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); -#elif defined ALPHA_BUILD +# elif defined ALPHA_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-red.ico")); -#elif defined BETA_BUILD +# elif defined BETA_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); -#else +# else app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); -#endif -#if (!defined(Q_OS_WINDOWS) && !defined(__APPLE__)) +# ifdef Q_OS_UNIX app.setDesktopFileName("net.86box.86Box"); +# endif #endif if (!pc_init_modules()) { From 1f6a5a8a957afe79a924f695539dc518e1af5ffc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Dec 2023 01:44:31 +0100 Subject: [PATCH 131/146] Added a missing #endif. --- src/qt/qt_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index bc95ad1d1d6..a361309841f 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -204,6 +204,7 @@ main(int argc, char *argv[]) app.setWindowIcon(QIcon(":/settings/win/icons/86Box-yellow.ico")); # else app.setWindowIcon(QIcon(":/settings/win/icons/86Box-gray.ico")); +# endif # ifdef Q_OS_UNIX app.setDesktopFileName("net.86box.86Box"); From 514212798294ad93f80f98cb16b31a4a4a762cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Castell=C3=B3?= Date: Sat, 30 Dec 2023 23:25:20 -0300 Subject: [PATCH 132/146] fixes typo on mac icon fix --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a361309841f..a83946ea3c0 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -195,7 +195,7 @@ main(int argc, char *argv[]) SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif -#ifndef Q_OS_APPLE +#ifndef __APPLE__ # ifdef RELEASE_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); # elif defined ALPHA_BUILD From 5cb239103947a44dd774ffb6a9611626c7498d73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Castell=C3=B3?= Date: Sun, 31 Dec 2023 00:09:50 -0300 Subject: [PATCH 133/146] Update src/qt/qt_main.cpp Accepted changes Co-authored-by: Alexander Babikov --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index a83946ea3c0..409a6324886 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -195,7 +195,7 @@ main(int argc, char *argv[]) SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif -#ifndef __APPLE__ +#ifndef Q_OS_MACOS # ifdef RELEASE_BUILD app.setWindowIcon(QIcon(":/settings/win/icons/86Box-green.ico")); # elif defined ALPHA_BUILD From ca21ea528a0f3278406fb24e797d43e2a32c7647 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 14:54:00 +0600 Subject: [PATCH 134/146] Matrox Productiva G100 working (expect maybe alpha stipple) --- src/video/vid_mga.c | 202 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 161 insertions(+), 41 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f064b4d341e..c2b4054543b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -120,6 +120,7 @@ #define REG_DR2_Z32MSB 0x2c64 #define REG_DR3_Z32LSB 0x2c68 #define REG_DR3_Z32MSB 0x2c6c +#define REG_TEXFILTER 0x2c58 #define REG_FIFOSTATUS 0x1e10 #define REG_STATUS 0x1e14 @@ -510,7 +511,8 @@ typedef struct mystique_t { texctl, textrans, zorg, ydst_lin, src_addr, z_base, iload_rem_data, highv_data, fogcol, fogxinc : 24, fogyinc : 24, fogstart : 24, - alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24; + alphactrl, alphaxinc : 24, alphayinc : 24, alphastart : 24, + texfilter; uint32_t src[4], ar[7], dr[16], tmr[9]; @@ -658,6 +660,15 @@ static const uint8_t trans_masks[16][16] = { static int8_t dither5[256][2][2]; static int8_t dither6[256][2][2]; +static double bayer_mat[4][4] = +{ + { 0.0, 8. / 16., 2. / 16., 10. / 16.}, + { 12. / 16., 4. / 16., 14. / 16., 6. / 16.}, + { 3. / 16., 11. / 16., 1. / 16., 9. / 16.}, + { 15. / 16., 7. / 16., 13. / 16., 5. / 16.}, +}; + +static const int grey_lut[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239 }; static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; @@ -2608,6 +2619,10 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) mystique->dwgreg.fogyinc = val; break; + case REG_TEXFILTER: + mystique->dwgreg.texfilter = val; + break; + default: mystique_accel_ctrl_write_b(addr, val & 0xff, priv); mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, priv); @@ -4828,45 +4843,18 @@ blit_trap(mystique_t *mystique) mystique->blitter_complete_refcount++; } -static int -texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) +static uint16_t texture_texel_fetch(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *tex_a, int *atransp, int s, int t, int tex_pitch) { - svga_t *svga = &mystique->svga; - - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; - const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; - const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; - uint16_t src = 0; - int s; - int t; - int tex_pitch = 1 << tex_shift; - - *tex_a = 255; - - if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) - { - tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; - if (tex_pitch == 0) - tex_pitch = 2048; - } - - if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { - const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + svga_t* svga = &mystique->svga; + uint16_t src = 0x0; - s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; - t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; - } else { - const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8] /*>> 16*/) : 0; + int atransp_dummy = 0; - s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q /*<< 8*/) >> s_shift; /*((16+20)-12);*/ - t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q /*<< 8*/) >> t_shift; /*((16+20)-9);*/ - } + if (!atransp) + atransp = &atransp_dummy; if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { if (s < 0) @@ -4915,10 +4903,11 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra break; case TEXCTL_TEXFORMAT_TW12: src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t * tex_pitch) + s) & mystique->vram_mask_w]; - *tex_r = ((src >> 8) & 0xf) << 3; - *tex_g = ((src >> 4) & 0xf) << 3; - *tex_b = (src & 0xf) << 3; - *tex_a = ((src >> 12) & 0xf) << 3; + *tex_r = ((src >> 8) & 0xf) << 4; + *tex_g = ((src >> 4) & 0xf) << 4; + *tex_b = (src & 0xf) << 4; + *tex_a = ((src >> 12) & 0xf) << 4; + pclog("TEXFORMAT_TW12\n"); if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; } else { @@ -4938,6 +4927,114 @@ texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atra fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); break; } + return src; +} + +static double lerp(double v0, double v1, double t) { + return (1. - t) * v0 + t * v1; +} + +static int +texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) +{ + svga_t *svga = &mystique->svga; + + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s; + int t; + int tex_pitch = 1 << tex_shift; + double s_frac = 0; + double t_frac = 0; + + *tex_a = 255; + + if (mystique->type >= MGA_G100 && (mystique->dwgreg.texctl & TEXCTL_TPITCHLIN)) + { + tex_pitch = (mystique->dwgreg.texctl & TEXCTL_TPITCHEXT_MASK) >> 9; + if (tex_pitch == 0) + tex_pitch = 2048; + } + + if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + + s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; + s_frac = (((int32_t) mystique->dwgreg.tmr[6] >> s_shift) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int32_t) mystique->dwgreg.tmr[7] >> t_shift) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + } else { + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? (0x100000000LL / (int64_t) (int32_t) mystique->dwgreg.tmr[8]) : 0; + + s = ((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) >> s_shift; + t = ((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) >> t_shift; + s_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << s_shift) - 1)) / (double)(1 << s_shift); + t_frac = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) & ((1 << t_shift) - 1)) / (double)(1 << t_shift); + } + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; + } else + s &= w_mask; + + if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; + } else + t &= h_mask; + + src = texture_texel_fetch(mystique, tex_r, tex_g, tex_b, tex_a, atransp, s, t, tex_pitch); + switch (mystique->dwgreg.texfilter & 3) + { + case 0: + s_frac = t_frac = 0; + break; + case 1: + case 2: + break; + case 3: + s_frac = t_frac = .25; + break; + } + if (s_frac && s != w_mask) + { + int s_tex_r = 0, s_tex_g = 0, s_tex_b = 0, s_tex_a = 255; + texture_texel_fetch(mystique, &s_tex_r, &s_tex_g, &s_tex_b, &s_tex_a, NULL, s + 1, t, tex_pitch); + *tex_r = (int)lerp(*tex_r, s_tex_r, s_frac); + *tex_g = (int)lerp(*tex_g, s_tex_g, s_frac); + *tex_b = (int)lerp(*tex_b, s_tex_b, s_frac); + *tex_a = (int)lerp(*tex_a, s_tex_a, s_frac); + if (*tex_r > 255) *tex_r = 255; + if (*tex_g > 255) *tex_g = 255; + if (*tex_b > 255) *tex_b = 255; + if (*tex_a > 255) *tex_a = 255; + } + if (t_frac && t != h_mask) + { + int t_tex_r = 0, t_tex_g = 0, t_tex_b = 0, t_tex_a = 255; + texture_texel_fetch(mystique, &t_tex_r, &t_tex_g, &t_tex_b, &t_tex_a, NULL, s, t + 1, tex_pitch); + *tex_r = (int)lerp(*tex_r, t_tex_r, t_frac); + *tex_g = (int)lerp(*tex_g, t_tex_g, t_frac); + *tex_b = (int)lerp(*tex_b, t_tex_b, t_frac); + *tex_a = (int)lerp(*tex_a, t_tex_a, t_frac); + if (*tex_r > 255) *tex_r = 255; + if (*tex_g > 255) *tex_g = 255; + if (*tex_b > 255) *tex_b = 255; + if (*tex_a > 255) *tex_a = 255; + } return ((src & tkmask) == tckey); } @@ -4995,7 +5092,7 @@ blit_texture_trap(mystique_t *mystique) int tex_r = 0; int tex_g = 0; int tex_b = 0; - int tex_a = 0; + int tex_a = 255; int ctransp; int atransp = 0; int i_r = 0; @@ -5107,6 +5204,25 @@ blit_texture_trap(mystique_t *mystique) if (final_a != 255) { + /* Does this actually work? I'm not sure. */ + if (final_a & 0xf) { + double threshold = bayer_mat[mystique->dwgreg.selline & 3][x_l & 3]; + double final_a_frac = (final_a & 0xf) / 16.; + if (final_a_frac >= threshold) { + if ((final_a >> 4) == 0x0) + final_a = grey_lut[1]; + else if ((final_a >> 4) == 0xf) + final_a = 255; + else + final_a = grey_lut[final_a >> 4]; + } else { + if ((final_a >> 4) == 0x0) + final_a = 0; + else + final_a = grey_lut[(final_a >> 4) - 1]; + } + } + if (dest32) { uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; uint8_t dst_b = dst_col & 0xFF; @@ -6480,7 +6596,11 @@ static const device_config_t millennium_ii_config[] = { .description = "Memory size", .type = CONFIG_SELECTION, .selection = - { + { + { + .description = "4 MB", + .value = 4 + }, { .description = "8 MB", .value = 8 From 6366e1c58c7b6bc48325cac3e088bdc8b6ece417 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 16:43:01 +0600 Subject: [PATCH 135/146] Implement proper alpha stipple --- src/video/vid_mga.c | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c2b4054543b..4f446cc62d9 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -668,8 +668,6 @@ static double bayer_mat[4][4] = { 15. / 16., 7. / 16., 13. / 16., 5. / 16.}, }; -static const int grey_lut[16] = { 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239 }; - static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; @@ -5204,44 +5202,15 @@ blit_texture_trap(mystique_t *mystique) if (final_a != 255) { - /* Does this actually work? I'm not sure. */ - if (final_a & 0xf) { + { double threshold = bayer_mat[mystique->dwgreg.selline & 3][x_l & 3]; - double final_a_frac = (final_a & 0xf) / 16.; + double final_a_frac = (final_a) / 255.; if (final_a_frac >= threshold) { - if ((final_a >> 4) == 0x0) - final_a = grey_lut[1]; - else if ((final_a >> 4) == 0xf) - final_a = 255; - else - final_a = grey_lut[final_a >> 4]; + final_a = 255; } else { - if ((final_a >> 4) == 0x0) - final_a = 0; - else - final_a = grey_lut[(final_a >> 4) - 1]; + goto skip_pixel; } } - - if (dest32) { - uint32_t dst_col = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; - uint8_t dst_b = dst_col & 0xFF; - uint8_t dst_g = (dst_col >> 8) & 0xFF; - uint8_t dst_r = (dst_col >> 16) & 0xFF; - - tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); - tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); - tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); - } else { - uint16_t dst_col = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; - uint8_t dst_b = (dst_col & 0x1f) << 3; - uint8_t dst_g = (dst_col & 0x7e0) >> 3; - uint8_t dst_r = (dst_col & 0xf800) >> 8; - - tex_r = (tex_r * ((final_a) / 255.)) + dst_r * ((255 - final_a) / 255.); - tex_g = (tex_g * ((final_a) / 255.)) + dst_g * ((255 - final_a) / 255.); - tex_b = (tex_b * ((final_a) / 255.)) + dst_b * ((255 - final_a) / 255.); - } } if (dest32) { From b1cf6c865756a9f3292c9b54a36fc1a7a34bac6b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 16:44:54 +0600 Subject: [PATCH 136/146] Remove logging --- src/video/vid_mga.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 4f446cc62d9..ab93e95b5ef 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4905,7 +4905,6 @@ static uint16_t texture_texel_fetch(mystique_t *mystique, int *tex_r, int *tex_g *tex_g = ((src >> 4) & 0xf) << 4; *tex_b = (src & 0xf) << 4; *tex_a = ((src >> 12) & 0xf) << 4; - pclog("TEXFORMAT_TW12\n"); if (mystique->dwgreg.texctl & TEXCTL_AZEROEXTEND) { *atransp = (((src >> 12) & 0xf) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key; } else { From 0ee66c4be8cd4750c566c382a0f05ad6c560ea51 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 16:45:52 +0600 Subject: [PATCH 137/146] Whitespace removal --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index ab93e95b5ef..33250b8e2d1 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6564,7 +6564,7 @@ static const device_config_t millennium_ii_config[] = { .description = "Memory size", .type = CONFIG_SELECTION, .selection = - { + { { .description = "4 MB", .value = 4 From 89f395ded1a5ae0e524417d7cbd8050e853e8007 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 31 Dec 2023 12:10:34 +0100 Subject: [PATCH 138/146] MGA: Fixed two warnings. --- src/video/vid_mga.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33250b8e2d1..f815a2ead8b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4934,10 +4934,7 @@ static double lerp(double v0, double v1, double t) { static int texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp, int *tex_a) { - svga_t *svga = &mystique->svga; - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; From 7b75d6f11d283526d03fceb31504b063c9ae4c3c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 19:18:20 +0600 Subject: [PATCH 139/146] Fix detection of MGA G100 video RAM when 16MB --- src/video/vid_mga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 33250b8e2d1..f4b4ecf27c7 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6371,6 +6371,8 @@ mystique_init(const device_t *info) NULL); mystique->svga.clock_gen = mystique; mystique->svga.getclock = mystique_getclock; + if (mystique->vram_size >= 16) + mystique->svga.decode_mask = mystique->svga.vram_mask; } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); From f8e55d0edcd77115573869c1a177339e0af3eac8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 19:47:25 +0600 Subject: [PATCH 140/146] MGA G100: Fix fog acceleration Minor variable cleanups --- src/video/vid_mga.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index f4b4ecf27c7..0767f8b3a8b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -456,8 +456,7 @@ typedef struct mystique_t { uint8_t pci_regs[256], crtcext_regs[6], xreg_regs[256], dmamap[16]; - int vram_size, crtcext_idx, xreg_idx, xzoomctrl, - pixel_count, trap_count; + int vram_size, crtcext_idx, xreg_idx, xzoomctrl; atomic_int busy, blitter_submit_refcount, blitter_submit_dma_refcount, blitter_complete_refcount, @@ -540,8 +539,7 @@ typedef struct mystique_t { struct { - atomic_int pri_pos, sec_pos, iload_pos, - pri_state, sec_state, iload_state, state; + atomic_int pri_state, sec_state, iload_state, state; atomic_uint primaddress, primend, secaddress, secend, pri_header, sec_header, @@ -4535,8 +4533,6 @@ blit_trap(mystique_t *mystique) int y; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_BLK: case DWGCTRL_ATYPE_RPL: @@ -4583,7 +4579,6 @@ blit_trap(mystique_t *mystique) else x_l++; - mystique->pixel_count++; } while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { @@ -4662,8 +4657,6 @@ blit_trap(mystique_t *mystique) x_l--; else x_l++; - - mystique->pixel_count++; } while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { @@ -4784,8 +4777,6 @@ blit_trap(mystique_t *mystique) x_l--; else x_l++; - - mystique->pixel_count++; } if (mystique->maccess_running & MACCESS_ZWIDTH) { @@ -5045,8 +5036,6 @@ blit_texture_trap(mystique_t *mystique) const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); - mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { case DWGCTRL_ATYPE_I: case DWGCTRL_ATYPE_ZI: @@ -5194,9 +5183,9 @@ blit_texture_trap(mystique_t *mystique) if (mystique->type >= MGA_G100 && (mystique->maccess_running & MACCESS_FOGEN)) { - tex_r = (tex_r * ((255 - i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * (i_fog / 255.); - tex_g = (tex_g * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * (i_fog / 255.); - tex_b = (tex_b * ((255 - i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * (i_fog / 255.); + tex_r = (tex_r * ((i_fog) / 255.)) + (mystique->dwgreg.fogcol >> 16) * ((255 - i_fog) / 255.); + tex_g = (tex_g * ((i_fog) / 255.)) + ((mystique->dwgreg.fogcol >> 8) & 0xFF) * ((255 - i_fog) / 255.); + tex_b = (tex_b * ((i_fog) / 255.)) + ((mystique->dwgreg.fogcol) & 0xFF) * ((255 - i_fog) / 255.); } if (final_a != 255) @@ -5234,8 +5223,6 @@ blit_texture_trap(mystique_t *mystique) else x_l++; - mystique->pixel_count++; - if (mystique->maccess_running & MACCESS_ZWIDTH) { mystique->dwgreg.extended_dr[0] += mystique->dwgreg.extended_dr[2]; mystique->dwgreg.dr[0] = (mystique->dwgreg.extended_dr[0] >> 16) & 0xFFFFFFFF; From 941d5bfdf814836d285cce3d87eedbe6adb9d880 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 31 Dec 2023 22:46:21 +0600 Subject: [PATCH 141/146] Fix busmastering under Windows 2000 --- src/video/vid_mga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 0767f8b3a8b..95a98521b5b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2175,6 +2175,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; + mystique->dma.words_expected = 0; thread_release_mutex(mystique->dma.lock); break; From 9966c6ced0e04309a9707e61e62415a0f0912411 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Jan 2024 16:51:31 +0500 Subject: [PATCH 142/146] Update the default copyright year --- CMakeLists.txt | 2 +- src/include_make/86box/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bc020f15b9..a6b50baf321 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,7 +196,7 @@ if(NOT EMU_BUILD_NUM) set(EMU_BUILD_NUM 0) endif() if(NOT EMU_COPYRIGHT_YEAR) - set(EMU_COPYRIGHT_YEAR 2023) + set(EMU_COPYRIGHT_YEAR 2024) endif() add_subdirectory(src) diff --git a/src/include_make/86box/version.h b/src/include_make/86box/version.h index 9a175be24e0..4004f58b3c5 100644 --- a/src/include_make/86box/version.h +++ b/src/include_make/86box/version.h @@ -34,7 +34,7 @@ #define EMU_VERSION_FULL EMU_VERSION #define EMU_VERSION_FULL_W EMU_VERSION_W -#define COPYRIGHT_YEAR "2022" +#define COPYRIGHT_YEAR "2024" /* Web URL info. */ #define EMU_SITE "86box.net" From b63bf09db3e66841ad5f0c044b333d0ae157a998 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Jan 2024 16:53:17 +0500 Subject: [PATCH 143/146] Replace the hardcoded year with COPYRIGHT_YEAR Replace the hardcoded copyright year with the COPYRIGHT_YEAR macro in the emulated Logitech serial mouse's self-report --- src/device/mouse_serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index e9531d78e50..08aee09d867 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -28,6 +28,7 @@ #include <86box/serial.h> #include <86box/mouse.h> #include <86box/plat.h> +#include <86box/version.h> #define SERMOUSE_PORT 0 /* attach to Serial0 */ @@ -537,7 +538,7 @@ ltsermouse_process_command(mouse_t *dev) [FORMAT_HEX] = 0x04, [FORMAT_MS_4BYTE] = 0x08, /* Guess */ [FORMAT_MS_WHEEL] = 0x08 }; /* Guess */ - const char *copr = "\r\n(C) 2023 86Box, Revision 3.0"; + const char *copr = "\r\n(C) " COPYRIGHT_YEAR " 86Box, Revision 3.0"; mouse_serial_log("ltsermouse_process_command(): %02X\n", dev->ib); dev->command = dev->ib; From af5aafbc0ef9eb56e7eaa17da1d74c5a30c785a2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 13:49:22 +0600 Subject: [PATCH 144/146] Make Matrox Productiva G100 usable as secondary display Confirmed working in Windows 98 SE at least --- src/video/vid_mga.c | 28 ++-- src/video/vid_table.c | 376 +++++++++++++++++++++--------------------- 2 files changed, 205 insertions(+), 199 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 95a98521b5b..e4d4ef6684d 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -2797,11 +2797,14 @@ static uint8_t mystique_readb_linear(uint32_t addr, void *priv) { const svga_t *svga = (svga_t *) priv; + mystique_t *mystique = (mystique_t *) svga->priv; - if (!svga->fast) - return svga_read_linear(addr, priv); + if (mystique->type < MGA_1064SG) { + if (!svga->fast) + return svga_read_linear(addr, priv); + } - cycles -= video_timing_read_b; + cycles -= svga->monitor->mon_video_timing_read_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2815,7 +2818,7 @@ mystique_readw_linear(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_read_w; + cycles -= svga->monitor->mon_video_timing_read_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2829,7 +2832,7 @@ mystique_readl_linear(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_read_l; + cycles -= svga->monitor->mon_video_timing_read_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2842,13 +2845,16 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; + mystique_t *mystique = (mystique_t *) svga->priv; - if (!svga->fast) { - svga_write_linear(addr, val, priv); - return; + if (mystique->type < MGA_1064SG) { + if (!svga->fast) { + svga_write_linear(addr, val, priv); + return; + } } - cycles -= video_timing_write_b; + cycles -= svga->monitor->mon_video_timing_write_b; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2863,7 +2869,7 @@ mystique_writew_linear(uint32_t addr, uint16_t val, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_w; + cycles -= svga->monitor->mon_video_timing_write_w; addr &= svga->decode_mask; if (addr >= svga->vram_max) @@ -2878,7 +2884,7 @@ mystique_writel_linear(uint32_t addr, uint32_t val, void *priv) { svga_t *svga = (svga_t *) priv; - cycles -= video_timing_write_l; + cycles -= svga->monitor->mon_video_timing_write_l; addr &= svga->decode_mask; if (addr >= svga->vram_max) diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 0b56f4d6980..844baa97ac9 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -77,198 +77,198 @@ static const device_t vid_internal_device = { static const VIDEO_CARD video_cards[] = { // clang-format off - { &vid_none_device }, - { &vid_internal_device }, - { &atiega800p_device }, - { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_isa_device }, - { &ati28800k_device }, - { &ati18800_vga88_device }, - { &ati28800_device }, - { &compaq_ati28800_device }, + { &vid_none_device }, + { &vid_internal_device }, + { &atiega800p_device }, + { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_isa_device }, + { &ati28800k_device }, + { &ati18800_vga88_device }, + { &ati28800_device }, + { &compaq_ati28800_device }, #if defined(DEV_BRANCH) && defined(USE_XL24) - { &ati28800_wonderxl24_device }, + { &ati28800_wonderxl24_device }, #endif - { &ati18800_device }, + { &ati18800_device }, #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - { &ati18800_wonder_device }, + { &ati18800_wonder_device }, #endif - { &cga_device }, - { &sega_device }, - { &gd5401_isa_device }, - { &gd5402_isa_device }, - { &gd5420_isa_device }, - { &gd5422_isa_device }, - { &gd5426_isa_device }, - { &gd5426_diamond_speedstar_pro_a1_isa_device }, - { &gd5428_boca_isa_device }, - { &gd5428_isa_device }, - { &gd5429_isa_device }, - { &gd5434_isa_device }, - { &gd5434_diamond_speedstar_64_a3_isa_device }, - { &compaq_cga_device }, - { &compaq_cga_2_device }, - { &cpqega_device }, - { &ega_device }, - { &g2_gc205_device }, - { &hercules_device, VIDEO_FLAG_TYPE_MDA }, - { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, - { &incolor_device }, - { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, - { &im1024_device }, - { &iskra_ega_device }, - { &et4000_kasan_isa_device }, - { &mda_device, VIDEO_FLAG_TYPE_MDA }, - { &genius_device }, - { &nga_device }, - { &ogc_device }, - { &oti037c_device }, - { &oti067_device }, - { &oti077_device }, - { ¶dise_pvga1a_device }, - { ¶dise_wd90c11_device }, - { ¶dise_wd90c30_device }, - { &colorplus_device }, - { &pgc_device }, - { &cga_pravetz_device }, - { &radius_svga_multiview_isa_device }, - { &realtek_rtg3106_device }, - { &s3_diamond_stealth_vram_isa_device }, - { &s3_orchid_86c911_isa_device }, - { &s3_ami_86c924_isa_device }, - { &s3_metheus_86c928_isa_device }, - { &s3_phoenix_86c801_isa_device }, - { &s3_spea_mirage_86c801_isa_device }, - { &sigma_device }, - { &tvga8900b_device }, - { &tvga8900d_device }, - { &tvga9000b_device }, - { &nec_sv9000_device }, - { &et4000k_isa_device }, - { &et2000_device }, - { &et3000_isa_device }, - { &et4000_isa_device }, - { &et4000w32_device }, - { &et4000w32i_isa_device }, - { &vga_device }, - { &v7_vga_1024i_device }, - { &wy700_device }, - { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, - { &gd5426_mca_device }, - { &gd5428_mca_device }, - { &et4000_mca_device }, - { &radius_svga_multiview_mca_device }, - { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_pci_device }, - { &mach64vt2_device }, - { &et4000w32p_videomagic_revb_pci_device }, - { &et4000w32p_revc_pci_device }, - { &et4000w32p_cardex_pci_device }, - { &et4000w32p_noncardex_pci_device }, - { &et4000w32p_pci_device }, - { &gd5430_pci_device, }, - { &gd5434_pci_device }, - { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5440_pci_device }, - { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5446_stb_pci_device,VIDEO_FLAG_TYPE_SPECIAL }, - { &gd5480_pci_device }, - { &s3_spea_mercury_lite_86c928_pci_device }, - { &s3_diamond_stealth64_964_pci_device }, - { &s3_elsa_winner2000_pro_x_964_pci_device }, - { &s3_mirocrystal_20sv_964_pci_device }, - { &s3_bahamas64_pci_device }, - { &s3_phoenix_vision864_pci_device }, - { &s3_diamond_stealth_se_pci_device }, - { &s3_phoenix_trio32_pci_device }, - { &s3_diamond_stealth64_pci_device }, - { &s3_9fx_pci_device }, - { &s3_phoenix_trio64_pci_device }, - { &s3_elsa_winner2000_pro_x_pci_device }, - { &s3_mirovideo_40sv_ergo_968_pci_device }, - { &s3_9fx_771_pci_device }, - { &s3_phoenix_vision968_pci_device }, - { &s3_spea_mercury_p64v_pci_device }, - { &s3_9fx_531_pci_device }, - { &s3_phoenix_vision868_pci_device }, - { &s3_cardex_trio64vplus_pci_device }, - { &s3_phoenix_trio64vplus_pci_device }, - { &s3_trio64v2_dx_pci_device }, - { &s3_virge_325_pci_device }, - { &s3_diamond_stealth_2000_pci_device }, - { &s3_diamond_stealth_3000_pci_device }, - { &s3_stb_velocity_3d_pci_device }, - { &s3_virge_375_pci_device }, - { &s3_diamond_stealth_2000pro_pci_device }, - { &s3_virge_385_pci_device }, - { &s3_virge_357_pci_device }, - { &s3_diamond_stealth_4000_pci_device }, - { &s3_trio3d2x_pci_device }, - { &millennium_device }, - { &millennium_ii_device }, - { &mystique_device }, - { &mystique_220_device }, - { &tgui9440_pci_device }, - { &tgui9660_pci_device }, - { &tgui9680_pci_device }, - { &voodoo_banshee_device }, - { &creative_voodoo_banshee_device }, - { &voodoo_3_1000_device }, - { &voodoo_3_2000_device }, - { &voodoo_3_3000_device }, - { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, - { &mach64gx_vlb_device }, - { &et4000w32i_vlb_device }, - { &et4000w32p_videomagic_revb_vlb_device }, - { &et4000w32p_revc_vlb_device }, - { &et4000w32p_cardex_vlb_device }, - { &et4000w32p_vlb_device }, - { &et4000w32p_noncardex_vlb_device }, - { &gd5424_vlb_device }, - { &gd5426_vlb_device }, - { &gd5428_vlb_device }, - { &gd5428_diamond_speedstar_pro_b1_vlb_device }, - { &gd5429_vlb_device }, - { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, - { &gd5430_vlb_device }, - { &gd5434_vlb_device }, - { &s3_metheus_86c928_vlb_device }, - { &s3_mirocrystal_8s_805_vlb_device }, - { &s3_mirocrystal_10sd_805_vlb_device }, - { &s3_phoenix_86c805_vlb_device }, - { &s3_spea_mirage_86c805_vlb_device }, - { &s3_diamond_stealth64_964_vlb_device }, - { &s3_mirocrystal_20sv_964_vlb_device }, - { &s3_mirocrystal_20sd_864_vlb_device }, - { &s3_bahamas64_vlb_device }, - { &s3_phoenix_vision864_vlb_device }, - { &s3_diamond_stealth_se_vlb_device }, - { &s3_phoenix_trio32_vlb_device }, - { &s3_diamond_stealth64_vlb_device }, - { &s3_9fx_vlb_device }, - { &s3_phoenix_trio64_vlb_device }, - { &s3_spea_mirage_p64_vlb_device }, - { &s3_phoenix_vision968_vlb_device }, - { &s3_phoenix_vision868_vlb_device }, - { &ht216_32_standalone_device }, - { &tgui9400cxi_device }, - { &tgui9440_vlb_device }, - { &s3_virge_357_agp_device }, - { &s3_diamond_stealth_4000_agp_device }, - { &s3_trio3d2x_agp_device }, - { &productiva_g100_device }, - { &velocity_100_agp_device }, - { &velocity_200_agp_device }, - { &voodoo_3_1000_agp_device }, - { &voodoo_3_2000_agp_device }, - { &voodoo_3_3000_agp_device }, - { &voodoo_3_3500_agp_ntsc_device }, - { &voodoo_3_3500_agp_pal_device }, - { &compaq_voodoo_3_3500_agp_device }, - { &voodoo_3_3500_se_agp_device }, - { &voodoo_3_3500_si_agp_device }, - { NULL } + { &cga_device }, + { &sega_device }, + { &gd5401_isa_device }, + { &gd5402_isa_device }, + { &gd5420_isa_device }, + { &gd5422_isa_device }, + { &gd5426_isa_device }, + { &gd5426_diamond_speedstar_pro_a1_isa_device }, + { &gd5428_boca_isa_device }, + { &gd5428_isa_device }, + { &gd5429_isa_device }, + { &gd5434_isa_device }, + { &gd5434_diamond_speedstar_64_a3_isa_device }, + { &compaq_cga_device }, + { &compaq_cga_2_device }, + { &cpqega_device }, + { &ega_device }, + { &g2_gc205_device }, + { &hercules_device, VIDEO_FLAG_TYPE_MDA }, + { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, + { &incolor_device }, + { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, + { &im1024_device }, + { &iskra_ega_device }, + { &et4000_kasan_isa_device }, + { &mda_device, VIDEO_FLAG_TYPE_MDA }, + { &genius_device }, + { &nga_device }, + { &ogc_device }, + { &oti037c_device }, + { &oti067_device }, + { &oti077_device }, + { ¶dise_pvga1a_device }, + { ¶dise_wd90c11_device }, + { ¶dise_wd90c30_device }, + { &colorplus_device }, + { &pgc_device }, + { &cga_pravetz_device }, + { &radius_svga_multiview_isa_device }, + { &realtek_rtg3106_device }, + { &s3_diamond_stealth_vram_isa_device }, + { &s3_orchid_86c911_isa_device }, + { &s3_ami_86c924_isa_device }, + { &s3_metheus_86c928_isa_device }, + { &s3_phoenix_86c801_isa_device }, + { &s3_spea_mirage_86c801_isa_device }, + { &sigma_device }, + { &tvga8900b_device }, + { &tvga8900d_device }, + { &tvga9000b_device }, + { &nec_sv9000_device }, + { &et4000k_isa_device }, + { &et2000_device }, + { &et3000_isa_device }, + { &et4000_isa_device }, + { &et4000w32_device }, + { &et4000w32i_isa_device }, + { &vga_device }, + { &v7_vga_1024i_device }, + { &wy700_device }, + { &mach32_mca_device, VIDEO_FLAG_TYPE_8514 }, + { &gd5426_mca_device }, + { &gd5428_mca_device }, + { &et4000_mca_device }, + { &radius_svga_multiview_mca_device }, + { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_pci_device }, + { &mach64vt2_device }, + { &et4000w32p_videomagic_revb_pci_device }, + { &et4000w32p_revc_pci_device }, + { &et4000w32p_cardex_pci_device }, + { &et4000w32p_noncardex_pci_device }, + { &et4000w32p_pci_device }, + { &gd5430_pci_device, }, + { &gd5434_pci_device }, + { &gd5436_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5440_pci_device }, + { &gd5446_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5446_stb_pci_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &gd5480_pci_device }, + { &s3_spea_mercury_lite_86c928_pci_device }, + { &s3_diamond_stealth64_964_pci_device }, + { &s3_elsa_winner2000_pro_x_964_pci_device }, + { &s3_mirocrystal_20sv_964_pci_device }, + { &s3_bahamas64_pci_device }, + { &s3_phoenix_vision864_pci_device }, + { &s3_diamond_stealth_se_pci_device }, + { &s3_phoenix_trio32_pci_device }, + { &s3_diamond_stealth64_pci_device }, + { &s3_9fx_pci_device }, + { &s3_phoenix_trio64_pci_device }, + { &s3_elsa_winner2000_pro_x_pci_device }, + { &s3_mirovideo_40sv_ergo_968_pci_device }, + { &s3_9fx_771_pci_device }, + { &s3_phoenix_vision968_pci_device }, + { &s3_spea_mercury_p64v_pci_device }, + { &s3_9fx_531_pci_device }, + { &s3_phoenix_vision868_pci_device }, + { &s3_cardex_trio64vplus_pci_device }, + { &s3_phoenix_trio64vplus_pci_device }, + { &s3_trio64v2_dx_pci_device }, + { &s3_virge_325_pci_device }, + { &s3_diamond_stealth_2000_pci_device }, + { &s3_diamond_stealth_3000_pci_device }, + { &s3_stb_velocity_3d_pci_device }, + { &s3_virge_375_pci_device }, + { &s3_diamond_stealth_2000pro_pci_device }, + { &s3_virge_385_pci_device }, + { &s3_virge_357_pci_device }, + { &s3_diamond_stealth_4000_pci_device }, + { &s3_trio3d2x_pci_device }, + { &millennium_device }, + { &millennium_ii_device }, + { &mystique_device }, + { &mystique_220_device }, + { &tgui9440_pci_device }, + { &tgui9660_pci_device }, + { &tgui9680_pci_device }, + { &voodoo_banshee_device }, + { &creative_voodoo_banshee_device }, + { &voodoo_3_1000_device }, + { &voodoo_3_2000_device }, + { &voodoo_3_3000_device }, + { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, + { &mach64gx_vlb_device }, + { &et4000w32i_vlb_device }, + { &et4000w32p_videomagic_revb_vlb_device }, + { &et4000w32p_revc_vlb_device }, + { &et4000w32p_cardex_vlb_device }, + { &et4000w32p_vlb_device }, + { &et4000w32p_noncardex_vlb_device }, + { &gd5424_vlb_device }, + { &gd5426_vlb_device }, + { &gd5428_vlb_device }, + { &gd5428_diamond_speedstar_pro_b1_vlb_device }, + { &gd5429_vlb_device }, + { &gd5430_diamond_speedstar_pro_se_a8_vlb_device }, + { &gd5430_vlb_device }, + { &gd5434_vlb_device }, + { &s3_metheus_86c928_vlb_device }, + { &s3_mirocrystal_8s_805_vlb_device }, + { &s3_mirocrystal_10sd_805_vlb_device }, + { &s3_phoenix_86c805_vlb_device }, + { &s3_spea_mirage_86c805_vlb_device }, + { &s3_diamond_stealth64_964_vlb_device }, + { &s3_mirocrystal_20sv_964_vlb_device }, + { &s3_mirocrystal_20sd_864_vlb_device }, + { &s3_bahamas64_vlb_device }, + { &s3_phoenix_vision864_vlb_device }, + { &s3_diamond_stealth_se_vlb_device }, + { &s3_phoenix_trio32_vlb_device }, + { &s3_diamond_stealth64_vlb_device }, + { &s3_9fx_vlb_device }, + { &s3_phoenix_trio64_vlb_device }, + { &s3_spea_mirage_p64_vlb_device }, + { &s3_phoenix_vision968_vlb_device }, + { &s3_phoenix_vision868_vlb_device }, + { &ht216_32_standalone_device }, + { &tgui9400cxi_device }, + { &tgui9440_vlb_device }, + { &s3_virge_357_agp_device }, + { &s3_diamond_stealth_4000_agp_device }, + { &s3_trio3d2x_agp_device }, + { &productiva_g100_device, VIDEO_FLAG_TYPE_SPECIAL }, + { &velocity_100_agp_device }, + { &velocity_200_agp_device }, + { &voodoo_3_1000_agp_device }, + { &voodoo_3_2000_agp_device }, + { &voodoo_3_3000_agp_device }, + { &voodoo_3_3500_agp_ntsc_device }, + { &voodoo_3_3500_agp_pal_device }, + { &compaq_voodoo_3_3500_agp_device }, + { &voodoo_3_3500_se_agp_device }, + { &voodoo_3_3500_si_agp_device }, + { NULL } // clang-format on }; From 318403b133f08a0260ee3b7a861dc3418ca5fe76 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 14:12:02 +0600 Subject: [PATCH 145/146] Fix G100 VBIOS mapping --- src/video/vid_mga.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index e4d4ef6684d..b4f84fb6233 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6202,9 +6202,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (!(mystique->pci_regs[0x43] & 0x40)) return; mystique->pci_regs[addr] = val; + if (addr == 0x30) + mystique->pci_regs[addr] &= 1; if (mystique->pci_regs[0x30] & 0x01) { uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); return; @@ -6228,11 +6230,11 @@ mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (val & 0x40) { if (mystique->pci_regs[0x30] & 0x01) { uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } else mem_mapping_disable(&mystique->bios_rom.mapping); } else - mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, 0x8000); + mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, (mystique->type == MGA_G100) ? 0x10000 : 0x8000); } break; @@ -6331,7 +6333,10 @@ mystique_init(const device_t *info) else romfn = ROM_MYSTIQUE_220; - rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (mystique->type == MGA_G100) + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else + rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&mystique->bios_rom.mapping); mystique->vram_size = device_get_config_int("memory"); From 64c930f95feaf4b674fda5a78bc44b0913fc9b84 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 2 Jan 2024 14:34:12 +0600 Subject: [PATCH 146/146] G100 is now correctly added as AGP device --- src/video/vid_mga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index b4f84fb6233..24a4e583594 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6396,7 +6396,7 @@ mystique_init(const device_t *info) if (romfn == NULL) pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); else - pci_add_card(PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); + pci_add_card((info->flags & DEVICE_AGP) ? PCI_ADD_AGP : PCI_ADD_NORMAL, mystique_pci_read, mystique_pci_write, mystique, &mystique->pci_slot); mystique->pci_regs[0x06] = 0x80; mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8];