From aa0b4dfab7c34569aea26f8ab98520b16c9d4885 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 17 Dec 2023 12:43:07 +0100 Subject: [PATCH 01/74] 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 4d8dea3ce..fb9fd70ce 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) { + default: + ret = dev->pmu_conf[addr]; + break; + case 0x10 ... 0x13: + if (dev->pmu_conf[0x5b] & 0x02) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; + break; + case 0x14 ... 0x17: + if (dev->pmu_conf[0x5b] & 0x04) + ret = 0x00; + else + ret = dev->pmu_conf[addr]; + break; case 0x42: - dev->pmu_conf[addr] &= 0xe0; + ret = (dev->pmu_conf[addr] & 0xf7) | (nvr_smi_status(dev->nvr) ? 0x08 : 0x00); break; case 0x43: - dev->pmu_conf[addr] &= 0xef; - acpi_ali_soft_smi_status_write(dev->acpi, 0); + ret = acpi_ali_soft_smi_status_read(dev->acpi) ? 0x10 : 0x00; break; + case 0x7f: + ret = 0x80; + break; + case 0xbc: + ret = inb(0x70); + 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; + 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 0x4e: - dev->pmu_conf[addr] &= 0xfa; - break; - case 0x4f: - dev->pmu_conf[addr] &= 0xfe; - 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 0x74: - dev->pmu_conf[addr] &= 0xcc; - break; + case 0x4e: + dev->pmu_conf[addr] &= 0xfa; + break; + case 0x4f: + dev->pmu_conf[addr] &= 0xfe; + break; - default: - 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 02/74] 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 b1ed7094f..8c4ad0de4 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 ae2ea260c..c16cd5efb 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 d1e14fb12..6c86bdebf 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 ecd17cadb..bac84ead4 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 03/74] 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 2f701b33f..cadf64bb8 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 04/74] 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 fb9fd70ce..fe3a0fda3 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 983f14d26..05c35e09b 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 bac84ead4..cf69997b0 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 05/74] 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 cadf64bb8..69d8de0f8 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 06/74] 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 69d8de0f8..c505b5cc2 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 07/74] 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 c505b5cc2..7b1db7cc8 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 08/74] 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 c505b5cc2..9289c83ce 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 5f5efcd9e..1479ea718 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 09/74] 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 9289c83ce..b2212d268 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 10/74] 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 7b1db7cc8..a1486cb27 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 11/74] 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 f35f729da..35e65cc18 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 12d5d6c26085d8380b35a7b14c06dfea85845d48 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Dec 2023 02:18:08 +0600 Subject: [PATCH 12/74] 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 d066adb73..0cf35bdd9 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 13/74] 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 0cf35bdd9..2c9561b02 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 14/74] 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 7b9d570bb..f9d10b380 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 15/74] 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 707590134..cd0279078 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 16/74] 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 cd0279078..c11479786 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 17/74] 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 180803c8a..ec13de928 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 396b39124..de27fcbb1 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 5847faa39..fd658eacf 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; - if (svga->crtc[0x17] & 4) { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; + 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 (!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 d4abebb39..626ddeca9 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 6317fb5a3..f7f377888 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 18/74] 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 35e65cc18..9a56acdd7 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 19/74] 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 2c9561b02..2d4d3be02 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 20/74] 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 2d4d3be02..2c9561b02 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 21/74] 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 2c9561b02..1cba098ef 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 22/74] 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 1cba098ef..bf73206dc 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 23/74] 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 bf73206dc..3fd143547 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 24/74] 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 bf73206dc..d6b07c68b 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 25/74] 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 ec13de928..ec241d613 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 de27fcbb1..396b39124 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 fd658eacf..f9dc8821e 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 626ddeca9..da77449b0 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 f7f377888..0131fa3a4 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 26/74] 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 f9dc8821e..09e813bab 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 27/74] 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 6c86bdebf..942eb9be7 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 28/74] 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 942eb9be7..afc73a0dd 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 29/74] 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 a3838ea59..8600fac3e 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 30/74] 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 8600fac3e..c00c7693b 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 31/74] MGA: 3D busmastering now works (albeit slowly) --- src/video/vid_mga.c | 50 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index c00c7693b..d0ec17bff 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--; - - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - //pclog("softrapen\n"); - mystique_update_irqs(mystique); - } - thread_release_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; + //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 32/74] 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 c859fe033..1d6526521 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 f3503caeb..e0252dd7a 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 33/74] 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 1d6526521..02a0026d8 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 34/74] 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 afc73a0dd..74a1f90ff 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))) - return 0xffff; + if ((addr >= s->mem_base) && (addr < (s->mem_base + 0xff))) + ret = rtl8139_io_readw(addr, priv); - return rtl8139_io_readw(addr, priv); + rtl8139_log("[%04X:%08X] [RWM] %08X = %04X\n", CS, cpu_state.pc, addr, ret); + + 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; - /* PCI vendor and device ID should be mirrored here */ - s->eeprom.contents[1] = 0x10EC; - s->eeprom.contents[2] = 0x8139; + /* prepare eeprom */ + eep_data[0] = 0x8129; - /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ + /* 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 */ #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 35/74] 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 d0ec17bff..498f2ff9c 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 36/74] 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 498f2ff9c..de6b1594f 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 37/74] 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 de6b1594f..8ee6e1897 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 38/74] 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 25b073fda..33914d017 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 39/74] 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 f306b6138..7ea28a4ce 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 40/74] 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 5672fb135..9521d5337 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 41/74] 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 8ee6e1897..675abd474 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 42/74] 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 8ee6e1897..07b0edfe8 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 43/74] 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 3d6d28bd0..afd075035 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 44/74] 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 da77449b0..7cd6c6f17 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 45/74] 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 7e476663c..469a4555e 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -2940,9 +2940,11 @@ rect_fill: } 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 @@ rect_fill: 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 @@ bitblt: 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 89abde977..5b8dedfbe 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 46/74] 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 afd075035..3d6d28bd0 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 47/74] 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 3d6d28bd0..afd075035 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 48/74] 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 afd075035..eb3a28fc9 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 49/74] 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 eb3a28fc9..7e077209a 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 50/74] 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 7e077209a..b69a65063 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 51/74] 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 b69a65063..2720bea68 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 52/74] 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 2720bea68..98e45fd2f 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 53/74] 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 98e45fd2f..45ecd012f 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 54/74] 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 d9f92add3..4bc020f15 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 396b39124..921b8e778 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 6635252a6..638837757 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 45ecd012f..4a4d9169e 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 0131fa3a4..ad6fca2c6 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 13dbdcefe..8e4b99b56 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 55/74] 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 682a66111..52a9c9b0a 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 396b39124..4d8302982 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 45ecd012f..1f93c339e 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 7a15dc1cf..e94916fd5 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 56/74] 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 52a9c9b0a..709641457 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 1f93c339e..a04187fbe 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 e94916fd5..18e0438fd 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 57/74] 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 74a81741b..119d3ad15 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 58/74] 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 119d3ad15..2eb129c07 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 59/74] 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 09e791c4e..ef489c445 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 60/74] 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 ef489c445..845a6f35e 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 61/74] 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 2eb129c07..4bc0f97f9 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 62/74] 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 709641457..fc6c02c20 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 4bc0f97f9..f0cbad9eb 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 1479ea718..be53a0170 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 18e0438fd..e3f4bff5e 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 63/74] 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 eb6eb4a75..8efba343e 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 c11479786..cd0279078 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 64/74] 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 cd0279078..6ae706cc8 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 65/74] 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 f0cbad9eb..19720f674 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 66/74] 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 8efba343e..b576fbf27 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 6ae706cc8..2349c67a1 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 67/74] 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 2349c67a1..8247ecfab 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 68/74] 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 19720f674..49d44c06d 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 69/74] 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 be53a0170..449c1b33c 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 70/74] 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 49d44c06d..2b5c92ed3 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 71/74] 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 fc6c02c20..f55ec930c 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 be53a0170..ed93a6f3d 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 72/74] 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 f55ec930c..b44f101cb 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 94759ae5d..c41624bf7 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 73/74] 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 c41624bf7..9f125fb72 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 74/74] 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 2b5c92ed3..35354b2ad 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];