From 606d569d05f3df155b6d37343be6ae135429c1a2 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 4 Jul 2025 20:12:21 -0400 Subject: [PATCH 01/54] Fix warning in qt_settingsnetwork.cpp --- src/qt/qt_settingsnetwork.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index e2cfe9f7d..2a8332f5c 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -142,7 +142,9 @@ SettingsNetwork::save() for (int i = 0; i < NET_CARD_MAX; ++i) { auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); +#if defined(__unix__) || defined(__APPLE__) auto *bridge_line = findChild(QString("bridgeTAPNIC%1").arg(i + 1)); +#endif net_cards_conf[i].device_num = cbox->currentData().toInt(); cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); net_cards_conf[i].net_type = cbox->currentData().toInt(); From 59ec9e2ed316356c0d8270abce3f8371fdc64d0c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 5 Jul 2025 04:13:50 +0200 Subject: [PATCH 02/54] QuadColor: Fix the "snow" in some modes. --- src/video/vid_cga_quadcolor.c | 59 +++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/src/video/vid_cga_quadcolor.c b/src/video/vid_cga_quadcolor.c index 5974682c8..045054592 100644 --- a/src/video/vid_cga_quadcolor.c +++ b/src/video/vid_cga_quadcolor.c @@ -324,13 +324,23 @@ quadcolor_render(quadcolor_t *quadcolor, int line) cols[0] = (attr >> 4) + 16; if (drawcursor) { for (column = 0; column < 8; column++) { - buffer32->line[line][(x << 3) + column + 8] - = (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15) | get_next_qc2_pixel(quadcolor); + uint32_t cga_color_idx = (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); + uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); + if (qc2_pixel_val != 0) { + buffer32->line[line][(x << 3) + column + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; + } else { + buffer32->line[line][(x << 3) + column + 8] = cga_color_idx; + } } } else { for (column = 0; column < 8; column++) { - buffer32->line[line][(x << 3) + column + 8] - = cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] | get_next_qc2_pixel(quadcolor); + uint32_t cga_color_idx = cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0]; + uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); + if (qc2_pixel_val != 0) { + buffer32->line[line][(x << 3) + column + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; + } else { + buffer32->line[line][(x << 3) + column + 8] = cga_color_idx; + } } } quadcolor->memaddr++; @@ -354,16 +364,26 @@ quadcolor_render(quadcolor_t *quadcolor, int line) if (drawcursor) { for (column = 0; column < 8; column++) { dat = (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); - buffer32->line[line][(x << 4) + (column << 1) + 8] = dat | get_next_qc2_pixel(quadcolor); - buffer32->line[line][(x << 4) + (column << 1) + 9] = dat | get_next_qc2_pixel(quadcolor); - + uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); + if (qc2_pixel_val != 0) { + buffer32->line[line][(x << 4) + (column << 1) + 8] = (dat & 0xF0) | qc2_pixel_val; + buffer32->line[line][(x << 4) + (column << 1) + 9] = (dat & 0xF0) | qc2_pixel_val; + } else { + buffer32->line[line][(x << 4) + (column << 1) + 8] = dat; + buffer32->line[line][(x << 4) + (column << 1) + 9] = dat; + } } } else { for (column = 0; column < 8; column++) { dat = cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0]; - buffer32->line[line][(x << 4) + (column << 1) + 8] = dat | get_next_qc2_pixel(quadcolor); - buffer32->line[line][(x << 4) + (column << 1) + 9] = dat | get_next_qc2_pixel(quadcolor); - + uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); + if (qc2_pixel_val != 0) { + buffer32->line[line][(x << 4) + (column << 1) + 8] = (dat & 0xF0) | qc2_pixel_val; + buffer32->line[line][(x << 4) + (column << 1) + 9] = (dat & 0xF0) | qc2_pixel_val; + } else { + buffer32->line[line][(x << 4) + (column << 1) + 8] = dat; + buffer32->line[line][(x << 4) + (column << 1) + 9] = dat; + } } } } @@ -391,8 +411,15 @@ quadcolor_render(quadcolor_t *quadcolor, int line) dat = 0; quadcolor->memaddr++; for (column = 0; column < 8; column++) { - buffer32->line[line][(x << 4) + (column << 1) + 8] = cols[dat >> 14] | get_next_qc2_pixel(quadcolor); - buffer32->line[line][(x << 4) + (column << 1) + 9] = cols[dat >> 14] | get_next_qc2_pixel(quadcolor); + uint32_t cga_color_idx = cols[dat >> 14]; + uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); + if (qc2_pixel_val != 0) { + buffer32->line[line][(x << 4) + (column << 1) + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; + buffer32->line[line][(x << 4) + (column << 1) + 9] = (cga_color_idx & 0xF0) | qc2_pixel_val; + } else { + buffer32->line[line][(x << 4) + (column << 1) + 8] = cga_color_idx; + buffer32->line[line][(x << 4) + (column << 1) + 9] = cga_color_idx; + } dat <<= 2; } } @@ -407,7 +434,13 @@ quadcolor_render(quadcolor_t *quadcolor, int line) dat = quadcolor->quadcolor_ctrl & 15; /* TODO: Is Quadcolor bg color actually relevant, here? Probably. See QC2 manual p.46 1. */; quadcolor->memaddr++; for (column = 0; column < 16; column++) { - buffer32->line[line][(x << 4) + column + 8] = cols[dat >> 15] | get_next_qc2_pixel(quadcolor); + uint32_t cga_color_idx = cols[dat >> 15]; + uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); + if (qc2_pixel_val != 0) { + buffer32->line[line][(x << 4) + column + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; + } else { + buffer32->line[line][(x << 4) + column + 8] = cga_color_idx; + } dat <<= 1; } } From 7600ebfd4661a75f04f5324c0cf4aa6e74925408 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 5 Jul 2025 05:38:50 +0200 Subject: [PATCH 03/54] QuadRam: Improve port 3DE heuristic to account of PC Paintbrush's behavior and fix the rendering, fixes #5747. --- src/video/vid_cga_quadcolor.c | 129 +++++++++++++++------------------- 1 file changed, 55 insertions(+), 74 deletions(-) diff --git a/src/video/vid_cga_quadcolor.c b/src/video/vid_cga_quadcolor.c index 045054592..642391679 100644 --- a/src/video/vid_cga_quadcolor.c +++ b/src/video/vid_cga_quadcolor.c @@ -155,7 +155,13 @@ quadcolor_out(uint16_t addr, uint8_t val, void *priv) case 0x3de: /* NOTE: the polarity of this register is the opposite of what the manual says */ if (quadcolor->has_quadcolor_2) - quadcolor->quadcolor_2_oe = !(val & 0x10); + /* + NOTE: PC Paintbrush writes FF and then gets stuck if it doesn't get enabled, + and then it expects to disable it with 0x00. The only way to square this + with the inverted polarity note above is if that was a value other than + 0x00 with bit 4 clear. + */ + quadcolor->quadcolor_2_oe = ((!(val & 0x10)) || (val == 0xff)) && (val != 0x00); return; default: @@ -290,22 +296,15 @@ quadcolor_render(quadcolor_t *quadcolor, int line) int32_t highres_graphics_flag = (CGA_MODE_FLAG_HIGHRES_GRAPHICS | CGA_MODE_FLAG_GRAPHICS); - if (((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag)) { - for (column = 0; column < 8; ++column) { - buffer32->line[line][column] = 0; - if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) - buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = (quadcolor->quadcolor_ctrl & 15); /* TODO: Is Quadcolor bg color actually relevant, here? */ - else - buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = (quadcolor->quadcolor_ctrl & 15); /* TODO: Is Quadcolor bg color actually relevant, here? */ - } - } else { - for (column = 0; column < 8; ++column) { - buffer32->line[line][column] = (quadcolor->cgacol & 15) + 16; - if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) - buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = (quadcolor->cgacol & 15) + 16; - else - buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = (quadcolor->cgacol & 15) + 16; - } + cols[0] = ((quadcolor->cgamode & highres_graphics_flag) == highres_graphics_flag) ? (quadcolor->quadcolor_ctrl & 15) : + (quadcolor->cgacol & 15); + + for (column = 0; column < 8; ++column) { + buffer32->line[line][column] = cols[0]; + if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) + buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 3) + 8] = cols[0]; + else + buffer32->line[line][column + (quadcolor->crtc[CGA_CRTC_HDISP] << 4) + 8] = cols[0]; } if (quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES) { /* 80-column text */ for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { @@ -322,30 +321,24 @@ quadcolor_render(quadcolor_t *quadcolor, int line) cols[1] = cols[0]; } else cols[0] = (attr >> 4) + 16; + uint8_t charline = quadcolor->scanline & 7; if (drawcursor) { for (column = 0; column < 8; column++) { - uint32_t cga_color_idx = (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); - uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); - if (qc2_pixel_val != 0) { - buffer32->line[line][(x << 3) + column + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; - } else { - buffer32->line[line][(x << 3) + column + 8] = cga_color_idx; - } + dat = (cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); + buffer32->line[line][(x << 3) + column + 8] = + dat | get_next_qc2_pixel(quadcolor); } } else { for (column = 0; column < 8; column++) { - uint32_t cga_color_idx = cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0]; - uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); - if (qc2_pixel_val != 0) { - buffer32->line[line][(x << 3) + column + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; - } else { - buffer32->line[line][(x << 3) + column + 8] = cga_color_idx; - } + dat = cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0]; + buffer32->line[line][(x << 3) + column + 8] = + dat | get_next_qc2_pixel(quadcolor); } } quadcolor->memaddr++; } - } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_GRAPHICS)) { /* not graphics (nor 80-column text) => 40-column text */ + } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_GRAPHICS)) { + /* Not graphics (nor 80-column text) => 40-column text. */ for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) { chr = quadcolor->vram[(quadcolor->page_offset ^ (quadcolor->memaddr << 1)) & DEVICE_VRAM_MASK]; @@ -361,33 +354,27 @@ quadcolor_render(quadcolor_t *quadcolor, int line) } else cols[0] = (attr >> 4) + 16; quadcolor->memaddr++; + uint8_t charline = quadcolor->scanline & 7; if (drawcursor) { for (column = 0; column < 8; column++) { - dat = (cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); - uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); - if (qc2_pixel_val != 0) { - buffer32->line[line][(x << 4) + (column << 1) + 8] = (dat & 0xF0) | qc2_pixel_val; - buffer32->line[line][(x << 4) + (column << 1) + 9] = (dat & 0xF0) | qc2_pixel_val; - } else { - buffer32->line[line][(x << 4) + (column << 1) + 8] = dat; - buffer32->line[line][(x << 4) + (column << 1) + 9] = dat; - } + dat = (cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0] ^ 15); + buffer32->line[line][(x << 4) + (column << 1) + 8] = + dat | get_next_qc2_pixel(quadcolor); + buffer32->line[line][(x << 4) + (column << 1) + 9] = + dat | get_next_qc2_pixel(quadcolor); } } else { for (column = 0; column < 8; column++) { - dat = cols[(fontdat[chr + quadcolor->fontbase][quadcolor->scanline & 7] & (1 << (column ^ 7))) ? 1 : 0]; - uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); - if (qc2_pixel_val != 0) { - buffer32->line[line][(x << 4) + (column << 1) + 8] = (dat & 0xF0) | qc2_pixel_val; - buffer32->line[line][(x << 4) + (column << 1) + 9] = (dat & 0xF0) | qc2_pixel_val; - } else { - buffer32->line[line][(x << 4) + (column << 1) + 8] = dat; - buffer32->line[line][(x << 4) + (column << 1) + 9] = dat; - } + dat = cols[(fontdat[chr + quadcolor->fontbase][charline] & (1 << (column ^ 7))) ? 1 : 0]; + buffer32->line[line][(x << 4) + (column << 1) + 8] = + dat | get_next_qc2_pixel(quadcolor); + buffer32->line[line][(x << 4) + (column << 1) + 9] = + dat | get_next_qc2_pixel(quadcolor); } } } - } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { /* not hi-res (but graphics) => 4-color mode */ + } else if (!(quadcolor->cgamode & CGA_MODE_FLAG_HIGHRES_GRAPHICS)) { + /* Not hi-res (but graphics) => 4-color mode. */ cols[0] = (quadcolor->cgacol & 15) | 16; col = (quadcolor->cgacol & 16) ? 24 : 16; if (quadcolor->cgamode & CGA_MODE_FLAG_BW) { @@ -405,42 +392,36 @@ quadcolor_render(quadcolor_t *quadcolor, int line) } for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) - dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000))] << 8) | - quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000) + 1)]; + dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000))] << 8) | + quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000) + 1)]; else dat = 0; quadcolor->memaddr++; for (column = 0; column < 8; column++) { - uint32_t cga_color_idx = cols[dat >> 14]; - uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); - if (qc2_pixel_val != 0) { - buffer32->line[line][(x << 4) + (column << 1) + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; - buffer32->line[line][(x << 4) + (column << 1) + 9] = (cga_color_idx & 0xF0) | qc2_pixel_val; - } else { - buffer32->line[line][(x << 4) + (column << 1) + 8] = cga_color_idx; - buffer32->line[line][(x << 4) + (column << 1) + 9] = cga_color_idx; - } + buffer32->line[line][(x << 4) + (column << 1) + 8] = cols[dat >> 14] | get_next_qc2_pixel(quadcolor); + buffer32->line[line][(x << 4) + (column << 1) + 9] = cols[dat >> 14] | get_next_qc2_pixel(quadcolor); dat <<= 2; } } - } else { /* 2-color hi-res graphics mode */ - cols[0] = quadcolor->quadcolor_ctrl & 15; /* background color (Quadcolor-specific) */; + } else { + /* 2-color hi-res graphics mode. */ + /* Background color (Quadcolor-specific). */ + cols[0] = quadcolor->quadcolor_ctrl & 15; cols[1] = (quadcolor->cgacol & 15) + 16; for (x = 0; x < quadcolor->crtc[CGA_CRTC_HDISP]; x++) { if (quadcolor->cgamode & CGA_MODE_FLAG_VIDEO_ENABLE) /* video enabled */ - dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000))] << 8) | - quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + ((quadcolor->scanline & 1) * 0x2000) + 1)]; + dat = (quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000))] << 8) | + quadcolor->vram[quadcolor->page_offset ^ (((quadcolor->memaddr << 1) & 0x1fff) + + ((quadcolor->scanline & 1) * 0x2000) + 1)]; else - dat = quadcolor->quadcolor_ctrl & 15; /* TODO: Is Quadcolor bg color actually relevant, here? Probably. See QC2 manual p.46 1. */; + /* TODO: Is Quadcolor bg color actually relevant, here? Probably. See QC2 manual p.46 1. */ + dat = quadcolor->quadcolor_ctrl & 15; quadcolor->memaddr++; for (column = 0; column < 16; column++) { - uint32_t cga_color_idx = cols[dat >> 15]; - uint8_t qc2_pixel_val = get_next_qc2_pixel(quadcolor); - if (qc2_pixel_val != 0) { - buffer32->line[line][(x << 4) + column + 8] = (cga_color_idx & 0xF0) | qc2_pixel_val; - } else { - buffer32->line[line][(x << 4) + column + 8] = cga_color_idx; - } + buffer32->line[line][(x << 4) + column + 8] = cols[dat >> 15] | get_next_qc2_pixel(quadcolor); dat <<= 1; } } From 382c9fd77f21202784af99fc4c457e89b99605cf Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 5 Jul 2025 10:56:09 +0200 Subject: [PATCH 04/54] Improve position of the NP4 430nx-based PCI slots --- src/machine/m_at_socket5.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index b2d3c46f3..03535ac88 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -95,7 +95,7 @@ machine_at_d842_init(const machine_t *model) fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios_versions"), 0); ret = bios_load_linear(fn, 0x000e0000, 131072, 0); device_context_restore(); - + machine_at_common_init(model); device_add(&ide_pci_2ch_device); @@ -195,10 +195,10 @@ machine_at_p54np4_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 06 = Slot 1 */ - pci_register_slot(0x05, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 05 = Slot 2 */ - pci_register_slot(0x04, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 04 = Slot 3 */ - pci_register_slot(0x03, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 03 = Slot 4 */ + pci_register_slot(0x07, PCI_CARD_NORMAL, 1, 2, 3, 4); /* 07 = Slot 1 */ + pci_register_slot(0x06, PCI_CARD_NORMAL, 2, 3, 4, 1); /* 06 = Slot 2 */ + pci_register_slot(0x05, PCI_CARD_NORMAL, 3, 4, 1, 2); /* 05 = Slot 3 */ + pci_register_slot(0x04, PCI_CARD_NORMAL, 4, 1, 2, 3); /* 04 = Slot 4 */ pci_register_slot(0x02, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); device_add(&i430nx_device); device_add(&sio_zb_device); @@ -237,7 +237,7 @@ machine_at_tek932_init(const machine_t *model) if (bios_only || !ret) return ret; - + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_2 | PCI_CAN_SWITCH_TYPE); From 2ef029fb058e1b711a3a02fa3adcc8b2ce1e6bc5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 5 Jul 2025 11:01:25 +0200 Subject: [PATCH 05/54] Fix one edge case of gpstatus stall. Which fixes Win3.1's Mach32 2.3 4bpp driver stalling. --- src/video/vid_ati_mach8.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index df8965caf..4bb678857 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -270,7 +270,7 @@ mach_log(const char *fmt, ...) static int mach_pixel_write(mach_t *mach) { - if (mach->accel.dp_config & 1) + if (mach->accel.dp_config & 0x01) return 1; return 0; @@ -279,7 +279,7 @@ mach_pixel_write(mach_t *mach) static int mach_pixel_read(mach_t *mach) { - if (mach->accel.dp_config & 1) + if (mach->accel.dp_config & 0x01) return 0; return 1; @@ -4303,6 +4303,10 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in dev->force_busy = 0; else if ((mono_src == 2) || (frgd_sel == 2) || (bkgd_sel == 2)) dev->force_busy = 0; + else if (!dev->accel.cmd_back) + dev->force_busy = 0; + + mach_log("2Force Busy=%d, frgdsel=%d, bkgdsel=%d, monosrc=%d, read=%d, dpconfig=%04x, back=%d.\n", dev->force_busy, frgd_sel, bkgd_sel, mono_src, mach_pixel_read(mach), mach->accel.dp_config, dev->accel.cmd_back); break; case 5: if (dev->accel.sx >= mach->accel.width) From f1a227f182641f1160523f5c6a605c674d3ef8e9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 5 Jul 2025 11:14:03 +0200 Subject: [PATCH 06/54] XGA changes of the day (July 5th, 2025) 1. Remove hackish ISA XGA add-on support (from now on, use the INMOS XGA card for ISA XGA support). 2. Correct timings when dispontime is on. 3. Add proper vga256 support on ISA XGA for NT 3.5x+ as well disable LFB support when asked (mainly when the aperture is on or when not extended mode) while keeping everything else happy. --- src/include/86box/vid_xga_device.h | 1 - src/qt/qt_settingsdisplay.cpp | 7 +- src/video/vid_svga.c | 4 +- src/video/vid_xga.c | 262 ++++++++++------------------- 4 files changed, 92 insertions(+), 182 deletions(-) diff --git a/src/include/86box/vid_xga_device.h b/src/include/86box/vid_xga_device.h index e337ef9d3..7a72e76f5 100644 --- a/src/include/86box/vid_xga_device.h +++ b/src/include/86box/vid_xga_device.h @@ -20,7 +20,6 @@ #ifdef EMU_DEVICE_H extern const device_t xga_device; -extern const device_t xga_isa_device; extern const device_t inmos_isa_device; #endif #endif /*VIDEO_XGA_DEVICE_H*/ diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 83e19aec7..e50f4ebe1 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -152,11 +152,8 @@ SettingsDisplay::on_pushButtonConfigure8514_clicked() void SettingsDisplay::on_pushButtonConfigureXga_clicked() { - if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) DeviceConfig::ConfigureDevice(&xga_device); - } else { - DeviceConfig::ConfigureDevice(&xga_isa_device); - } } void @@ -189,7 +186,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) bool videoCardHasXga = ((videoCard[0] == VID_INTERNAL) ? machine_has_flags(machineId, MACHINE_VIDEO_XGA) : (video_card_get_flags(videoCard[0]) == VIDEO_FLAG_TYPE_XGA)); bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514); - bool machineSupportsXga = (((machineHasIsa16 && device_available(&xga_isa_device)) || (machineHasMca && device_available(&xga_device))) && !videoCardHasXga); + bool machineSupportsXga = ((machineHasMca && device_available(&xga_device)) && !videoCardHasXga); bool machineSupportsDa2 = machineHasMca && device_available(&ps55da2_device); ui->checkBox8514->setEnabled(machineSupports8514); diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 8ed71645e..7b3f32a77 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1101,8 +1101,8 @@ svga_recalctimings(svga_t *svga) if (xga_active && (svga->xga != NULL)) { if (xga->on) { - disptime_xga = xga->h_total ? xga->h_total : TIMER_USEC; - _dispontime_xga = xga->h_disp; + disptime_xga = xga->h_total; + _dispontime_xga = xga->h_disp_time; } } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 8f4dc0d0e..0223e8b91 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -35,6 +35,7 @@ #include <86box/vid_svga_render.h> #include <86box/vid_xga_device.h> #include "cpu.h" +#include <86box/plat.h> #include <86box/plat_unused.h> #define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" @@ -161,31 +162,19 @@ xga_updatemapping(svga_t *svga) switch (xga->op_mode & 7) { case 0: xga_log("XGA: VGA mode address decode disabled.\n"); + mem_mapping_disable(&xga->linear_mapping); break; case 1: xga_log("XGA: VGA mode address decode enabled.\n"); - if (xga->base_addr_1mb) { - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - mem_mapping_enable(&xga->linear_mapping); - } else if (xga->linear_base) { - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - mem_mapping_enable(&xga->linear_mapping); - } else - mem_mapping_disable(&xga->linear_mapping); + mem_mapping_disable(&xga->linear_mapping); break; case 2: xga_log("XGA: 132-Column mode address decode disabled.\n"); + mem_mapping_disable(&xga->linear_mapping); break; case 3: xga_log("XGA: 132-Column mode address decode enabled.\n"); - if (xga->base_addr_1mb) { - mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); - mem_mapping_enable(&xga->linear_mapping); - } else if (xga->linear_base) { - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - mem_mapping_enable(&xga->linear_mapping); - } else - mem_mapping_disable(&xga->linear_mapping); + mem_mapping_disable(&xga->linear_mapping); break; default: xga_log("XGA: Extended Graphics mode, ap=%d.\n", xga->aperture_cntl); @@ -225,12 +214,14 @@ xga_updatemapping(svga_t *svga) } break; case 1: + mem_mapping_disable(&xga->linear_mapping); xga_log("XGA: 64KB aperture at A0000.\n"); mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); xga->banked_mask = 0xffff; break; case 2: + mem_mapping_disable(&xga->linear_mapping); xga_log("XGA: 64KB aperture at B0000.\n"); mem_mapping_set_handler(&svga->mapping, xga_read, xga_readw, xga_readl, xga_write, xga_writew, xga_writel); mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x10000); @@ -276,6 +267,7 @@ xga_recalctimings(svga_t *svga) xga->v_blankstart = xga->vblankstart + 1; xga->h_disp = (xga->hdisp + 1) << 3; + xga->h_disp_time = xga->h_disp >> 3; xga->rowoffset = xga->pix_map_width; @@ -292,7 +284,6 @@ xga_recalctimings(svga_t *svga) xga->memaddr_latch = xga->disp_start_addr; - xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x, dispcntl2=%02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80, xga->disp_cntl_2 & 0xc0); switch ((xga->clk_sel_1 >> 2) & 3) { case 0: @@ -329,6 +320,8 @@ xga_recalctimings(svga_t *svga) svga->render_xga = xga_render_blank; break; } + + xga_log("XGA: H_TOTAL=%d, rowoffset=%x, rowcount=%x, memaddr_latch=%06x, bpp type=%d.\n", xga->h_total, xga->rowoffset, xga->rowcount, xga->memaddr_latch, xga->disp_cntl_2 & 7); } } @@ -584,9 +577,9 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga->ap_idx = val; xga_log("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); - if ((xga->op_mode & 7) < 4) { + if ((xga->op_mode & 7) < 4) xga->write_bank = xga->read_bank = 0; - } else { + else { if (xga->base_addr_1mb) { if (xga->aperture_cntl) { xga->write_bank = (xga->ap_idx & 0x3f) << 16; @@ -1007,6 +1000,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int uint32_t addr = base; int bits; uint32_t byte; + uint8_t mask; uint8_t px; int skip = 0; @@ -1022,13 +1016,13 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else byte = mem_readb_phys(addr); - xga_log("1. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->accel.pat_src); if ((xga->accel.px_map_format[xga->accel.src_map] & 0x08) && !(xga->access_mode & 0x08)) bits = (x & 7); else bits = 7 - (x & 7); px = (byte >> bits) & 1; + xga_log("1bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, px=%x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, px, x, y, skip); return px; case 2: /*4-bit*/ addr += (y * (width >> 1)); @@ -1038,7 +1032,17 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else byte = mem_readb_phys(addr); - xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip); + if (xga->accel.px_map_format[map] & 0x08) + mask = ((1 - (x & 1)) << 2); + else + mask = ((x & 1) << 2); + + if (xga->access_mode & 0x08) + mask ^= 0x04; + + byte = (byte >> mask) & 0x0f; + + xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d, mask=%02x.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip, mask); return byte; case 3: /*8-bit*/ addr += (y * width); @@ -1091,11 +1095,11 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else byte = mem_readb_phys(addr); + xga_log("2. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[map] & 0x0f), xga->accel.pat_src); if (xga->access_mode & 0x08) mask = 1 << (7 - (x & 7)); else { if ((xga->accel.px_map_format[map] & 0x08) || (xga->accel.px_map_format[xga->accel.src_map] & 0x08)) { - xga_log("2. AccessMode=%02x, SRCMAP=%02x, DSTMAP=%02x, PAT=%02x.\n", xga->access_mode & 0x0f, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[map] & 0x0f), xga->accel.pat_src); mask = 1 << (x & 7); } else mask = 1 << (7 - (x & 7)); @@ -1124,9 +1128,15 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui byte = mem_readb_phys(addr); if (xga->accel.px_map_format[map] & 0x08) - mask = 0x0f << ((x & 1) << 2); + mask = ((1 - (x & 1)) << 2); else - mask = 0x0f << ((1 - (x & 1)) << 2); + mask = ((x & 1) << 2); + + if (xga->access_mode & 0x08) + mask ^= 0x04; + + pixel <<= mask; + mask = 0x0f << mask; byte = (byte & ~mask) | (pixel & mask); if (!skip) { @@ -1606,6 +1616,7 @@ xga_bitblt(svga_t *svga) xga->accel.sx += xdir; dx += xdir; + xga->accel.x--; if (xga->accel.x < 0) { xga->accel.x = xga->accel.blt_width & 0xfff; @@ -1781,6 +1792,7 @@ xga_bitblt(svga_t *svga) } xga->accel.sx += xdir; + if (xga->accel.pattern) xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth); else @@ -2631,24 +2643,53 @@ xga_render_4bpp(svga_t *svga) if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; - xga->lastline_draw = xga->displine; - for (int x = 0; x <= xga->h_disp; x += 8) { + for (int x = 0; x <= xga->h_disp; x += 16) { dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]); - p[0] = xga->pallook[dat & 0x0f]; - p[1] = xga->pallook[(dat >> 8) & 0x0f]; - p[2] = xga->pallook[(dat >> 16) & 0x0f]; - p[3] = xga->pallook[(dat >> 24) & 0x0f]; + if (xga->access_mode & 0x08) { + p[1] = xga->pallook[dat & 0x0f]; + p[0] = xga->pallook[(dat >> 4) & 0x0f]; + p[3] = xga->pallook[(dat >> 8) & 0x0f]; + p[2] = xga->pallook[(dat >> 12) & 0x0f]; + p[5] = xga->pallook[(dat >> 16) & 0x0f]; + p[4] = xga->pallook[(dat >> 20) & 0x0f]; + p[7] = xga->pallook[(dat >> 24) & 0x0f]; + p[6] = xga->pallook[(dat >> 28) & 0x0f]; + } else { + p[0] = xga->pallook[dat & 0x0f]; + p[1] = xga->pallook[(dat >> 4) & 0x0f]; + p[2] = xga->pallook[(dat >> 8) & 0x0f]; + p[3] = xga->pallook[(dat >> 12) & 0x0f]; + p[4] = xga->pallook[(dat >> 16) & 0x0f]; + p[5] = xga->pallook[(dat >> 20) & 0x0f]; + p[6] = xga->pallook[(dat >> 24) & 0x0f]; + p[7] = xga->pallook[(dat >> 28) & 0x0f]; + } - dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 2) & xga->vram_mask]); - p[4] = xga->pallook[dat & 0x0f]; - p[5] = xga->pallook[(dat >> 8) & 0x0f]; - p[6] = xga->pallook[(dat >> 16) & 0x0f]; - p[7] = xga->pallook[(dat >> 24) & 0x0f]; + dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]); + if (xga->access_mode & 0x08) { + p[9] = xga->pallook[dat & 0x0f]; + p[8] = xga->pallook[(dat >> 4) & 0x0f]; + p[11] = xga->pallook[(dat >> 8) & 0x0f]; + p[10] = xga->pallook[(dat >> 12) & 0x0f]; + p[13] = xga->pallook[(dat >> 16) & 0x0f]; + p[12] = xga->pallook[(dat >> 20) & 0x0f]; + p[15] = xga->pallook[(dat >> 24) & 0x0f]; + p[14] = xga->pallook[(dat >> 28) & 0x0f]; + } else { + p[8] = xga->pallook[dat & 0x0f]; + p[9] = xga->pallook[(dat >> 4) & 0x0f]; + p[10] = xga->pallook[(dat >> 8) & 0x0f]; + p[11] = xga->pallook[(dat >> 12) & 0x0f]; + p[12] = xga->pallook[(dat >> 16) & 0x0f]; + p[13] = xga->pallook[(dat >> 20) & 0x0f]; + p[14] = xga->pallook[(dat >> 24) & 0x0f]; + p[15] = xga->pallook[(dat >> 28) & 0x0f]; + } xga->memaddr += 8; - p += 8; + p += 16; } xga->memaddr &= xga->vram_mask; } @@ -2789,6 +2830,7 @@ xga_write(uint32_t addr, uint8_t val, void *priv) addr &= xga->banked_mask; addr += xga->write_bank; + xga_log("WriteBankedB addr=%08x, val=%02x, addrshift1=%08x.\n", addr, val, addr >> 1); if (addr >= xga->vram_size) return; @@ -2806,6 +2848,7 @@ xga_writew(uint32_t addr, uint16_t val, void *priv) addr &= xga->banked_mask; addr += xga->write_bank; + xga_log("WriteBankedW addr=%08x, val=%04x, addrshift1=%08x.\n", addr, val, addr >> 1); if (addr >= xga->vram_size) return; @@ -2824,6 +2867,7 @@ xga_writel(uint32_t addr, uint32_t val, void *priv) addr &= xga->banked_mask; addr += xga->write_bank; + xga_log("WriteBankedL addr=%08x, val=%08x, addrshift1=%08x.\n", addr, val, addr >> 1); if (addr >= xga->vram_size) return; @@ -2971,7 +3015,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) return; } - addr &= (xga->vram_size - 1); + addr &= xga->vram_mask; if (addr >= xga->vram_size) { xga_log("Write Linear Over!.\n"); @@ -3026,7 +3070,7 @@ xga_read_linear(uint32_t addr, void *priv) if (!xga->on) return svga_read_linear(addr, svga); - addr &= (xga->vram_size - 1); + addr &= xga->vram_mask; if (addr >= xga->vram_size) { xga_log("Read Linear Over ADDR=%x!.\n", addr); @@ -3121,10 +3165,10 @@ xga_poll(void *priv) svga->render_xga(svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; xga_render_overscan_left(xga, svga); xga_render_overscan_right(xga, svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; if (xga->hwcursor_on) { xga_hwcursor_draw(svga, xga->displine + svga->y_add); @@ -3229,11 +3273,11 @@ xga_poll(void *priv) } if (xga->vc == xga->v_total) { xga->vc = 0; - xga->scanline = 0; + xga->scanline = 0; xga->dispon = 1; xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; - svga->x_add = (overscan_x >> 1); + svga->x_add = svga->left_overscan; xga->hwcursor_on = 0; xga->hwcursor_latch = xga->hwcursor; @@ -3273,8 +3317,6 @@ xga_mca_write(int port, uint8_t val, void *priv) /* Save the MCA register value. */ xga->pos_regs[port & 7] = val; - if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/ - xga->pos_regs[4] |= 1; if (xga->pos_regs[2] & 1) { xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; @@ -3361,7 +3403,6 @@ xga_pos_in(uint16_t addr, void *priv) ret = xga->pos_regs[3]; ret |= (xga->dma_channel << 3); } - xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; case 0x0104: @@ -3465,11 +3506,8 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) break; case 0x0104: xga_log("104Write=%02x.\n", val); - if ((xga->pos_idx & 3) == 0) { + if ((xga->pos_idx & 3) == 0) xga->pos_regs[4] = val; - if (!(xga->pos_regs[4] & 0x01)) /*4MB addressing on systems with more than 15MB of memory*/ - xga->pos_regs[4] |= 0x01; - } break; case 0x0105: xga_log("105Write=%02x.\n", val); @@ -3515,13 +3553,11 @@ xga_init(const device_t *info) svga->xga = xga; - xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr"); - xga->instance_isa = device_get_config_int("instance"); xga->type = device_get_config_int("type"); xga->dma_channel = device_get_config_int("dma"); xga->bus = info->flags; - xga->vram_size = (1024 << 10); + xga->vram_size = 1024 << 10; xga->vram_mask = xga->vram_size - 1; xga->vram = calloc(xga->vram_size, 1); xga->changedvram = calloc((xga->vram_size >> 12) + 1, 1); @@ -3548,25 +3584,6 @@ xga_init(const device_t *info) mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, xga_memio_writeb, xga_memio_writew, xga_memio_writel, xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); - } else { - xga->pos_regs[2] = (xga->instance_isa << 1) | xga->ext_mem_addr; - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); - xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; - xga->pos_regs[2] |= 0x01; - xga->pos_regs[4] |= 0x01; - if (mem_size >= 15360) - xga->pos_regs[5] = 0; - else { - xga->pos_regs[5] = ((mem_size * 64) >> 0x10) + 1; - if (xga->pos_regs[5] == 0x10) - xga->pos_regs[5] = 0x00; - } - xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; - xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, xga->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, - xga_memio_writeb, xga_memio_writew, xga_memio_writel, - xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); } } @@ -3585,10 +3602,6 @@ xga_init(const device_t *info) } else { io_sethandler(0x0096, 0x0001, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); io_sethandler(0x0100, 0x0010, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); - if (xga_standalone_enabled) { - io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); - } } return svga; } @@ -3678,89 +3691,6 @@ static const device_config_t xga_mca_configuration[] = { // clang-format on }; -static const device_config_t xga_isa_configuration[] = { - // clang-format off - { - .name = "type", - .description = "XGA type", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "XGA-1", .value = 0 }, - { .description = "XGA-2", .value = 1 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "instance", - .description = "Instance", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 6, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "0 (2100h-210Fh)", .value = 0 }, - { .description = "1 (2110h-211Fh)", .value = 1 }, - { .description = "2 (2120h-212Fh)", .value = 2 }, - { .description = "3 (2130h-213Fh)", .value = 3 }, - { .description = "4 (2140h-214Fh)", .value = 4 }, - { .description = "5 (2150h-215Fh)", .value = 5 }, - { .description = "6 (2160h-216Fh)", .value = 6 }, - { .description = "7 (2170h-217Fh)", .value = 7 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "ext_mem_addr", - .description = "MMIO Address", - .type = CONFIG_HEX16, - .default_string = NULL, - .default_int = 0x00f0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "C800h", .value = 0x0040 }, - { .description = "CA00h", .value = 0x0050 }, - { .description = "CC00h", .value = 0x0060 }, - { .description = "CE00h", .value = 0x0070 }, - { .description = "D000h", .value = 0x0080 }, - { .description = "D200h", .value = 0x0090 }, - { .description = "D400h", .value = 0x00a0 }, - { .description = "D600h", .value = 0x00b0 }, - { .description = "D800h", .value = 0x00c0 }, - { .description = "DA00h", .value = 0x00d0 }, - { .description = "DC00h", .value = 0x00e0 }, - { .description = "DE00h", .value = 0x00f0 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 7, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "Disabled", .value = 0 }, - { .description = "DMA 6", .value = 6 }, - { .description = "DMA 7", .value = 7 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { .name = "", .description = "", .type = CONFIG_END } - // clang-format on -}; - static const device_config_t xga_inmos_isa_configuration[] = { // clang-format off { @@ -3812,20 +3742,6 @@ const device_t xga_device = { .config = xga_mca_configuration }; -const device_t xga_isa_device = { - .name = "XGA (ISA)", - .internal_name = "xga_isa", - .flags = DEVICE_ISA16, - .local = 0, - .init = xga_init, - .close = xga_close, - .reset = xga_reset, - .available = xga_available, - .speed_changed = xga_speed_changed, - .force_redraw = xga_force_redraw, - .config = xga_isa_configuration -}; - const device_t inmos_isa_device = { .name = "INMOS XGA (ISA)", .internal_name = "inmos_xga_isa", @@ -3848,6 +3764,4 @@ xga_device_add(void) if (machine_has_bus(machine, MACHINE_BUS_MCA)) device_add(&xga_device); - else - device_add(&xga_isa_device); } From c1d557356cab1054abc01e351e5735b692648900 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 5 Jul 2025 17:08:12 +0200 Subject: [PATCH 07/54] Some more XGA fixes Which fix OS/2's 4bpp rendering in a similar way to Win3.1. --- src/video/vid_xga.c | 69 +++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 0223e8b91..95bcbc214 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -1032,13 +1032,12 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else byte = mem_readb_phys(addr); - if (xga->accel.px_map_format[map] & 0x08) + if ((xga->accel.px_map_format[map] & 0x08) && (xga->access_mode & 0x08)) mask = ((1 - (x & 1)) << 2); - else + else { mask = ((x & 1) << 2); - - if (xga->access_mode & 0x08) mask ^= 0x04; + } byte = (byte >> mask) & 0x0f; @@ -1127,13 +1126,13 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else byte = mem_readb_phys(addr); - if (xga->accel.px_map_format[map] & 0x08) + if ((xga->accel.px_map_format[map] & 0x08) && (xga->access_mode & 0x08)) mask = ((1 - (x & 1)) << 2); - else + else { mask = ((x & 1) << 2); - - if (xga->access_mode & 0x08) mask ^= 0x04; + } + xga_log("4bpp Write: AccessMode=%02x.\n", xga->access_mode & 0x08); pixel <<= mask; mask = 0x0f << mask; @@ -2647,46 +2646,24 @@ xga_render_4bpp(svga_t *svga) for (int x = 0; x <= xga->h_disp; x += 16) { dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]); - if (xga->access_mode & 0x08) { - p[1] = xga->pallook[dat & 0x0f]; - p[0] = xga->pallook[(dat >> 4) & 0x0f]; - p[3] = xga->pallook[(dat >> 8) & 0x0f]; - p[2] = xga->pallook[(dat >> 12) & 0x0f]; - p[5] = xga->pallook[(dat >> 16) & 0x0f]; - p[4] = xga->pallook[(dat >> 20) & 0x0f]; - p[7] = xga->pallook[(dat >> 24) & 0x0f]; - p[6] = xga->pallook[(dat >> 28) & 0x0f]; - } else { - p[0] = xga->pallook[dat & 0x0f]; - p[1] = xga->pallook[(dat >> 4) & 0x0f]; - p[2] = xga->pallook[(dat >> 8) & 0x0f]; - p[3] = xga->pallook[(dat >> 12) & 0x0f]; - p[4] = xga->pallook[(dat >> 16) & 0x0f]; - p[5] = xga->pallook[(dat >> 20) & 0x0f]; - p[6] = xga->pallook[(dat >> 24) & 0x0f]; - p[7] = xga->pallook[(dat >> 28) & 0x0f]; - } + p[1] = xga->pallook[dat & 0x0f]; + p[0] = xga->pallook[(dat >> 4) & 0x0f]; + p[3] = xga->pallook[(dat >> 8) & 0x0f]; + p[2] = xga->pallook[(dat >> 12) & 0x0f]; + p[5] = xga->pallook[(dat >> 16) & 0x0f]; + p[4] = xga->pallook[(dat >> 20) & 0x0f]; + p[7] = xga->pallook[(dat >> 24) & 0x0f]; + p[6] = xga->pallook[(dat >> 28) & 0x0f]; dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]); - if (xga->access_mode & 0x08) { - p[9] = xga->pallook[dat & 0x0f]; - p[8] = xga->pallook[(dat >> 4) & 0x0f]; - p[11] = xga->pallook[(dat >> 8) & 0x0f]; - p[10] = xga->pallook[(dat >> 12) & 0x0f]; - p[13] = xga->pallook[(dat >> 16) & 0x0f]; - p[12] = xga->pallook[(dat >> 20) & 0x0f]; - p[15] = xga->pallook[(dat >> 24) & 0x0f]; - p[14] = xga->pallook[(dat >> 28) & 0x0f]; - } else { - p[8] = xga->pallook[dat & 0x0f]; - p[9] = xga->pallook[(dat >> 4) & 0x0f]; - p[10] = xga->pallook[(dat >> 8) & 0x0f]; - p[11] = xga->pallook[(dat >> 12) & 0x0f]; - p[12] = xga->pallook[(dat >> 16) & 0x0f]; - p[13] = xga->pallook[(dat >> 20) & 0x0f]; - p[14] = xga->pallook[(dat >> 24) & 0x0f]; - p[15] = xga->pallook[(dat >> 28) & 0x0f]; - } + p[9] = xga->pallook[dat & 0x0f]; + p[8] = xga->pallook[(dat >> 4) & 0x0f]; + p[11] = xga->pallook[(dat >> 8) & 0x0f]; + p[10] = xga->pallook[(dat >> 12) & 0x0f]; + p[13] = xga->pallook[(dat >> 16) & 0x0f]; + p[12] = xga->pallook[(dat >> 20) & 0x0f]; + p[15] = xga->pallook[(dat >> 24) & 0x0f]; + p[14] = xga->pallook[(dat >> 28) & 0x0f]; xga->memaddr += 8; p += 16; From 9cad5f501b5c5158c220caa00ff77c399f56f3fb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 6 Jul 2025 01:21:34 +0600 Subject: [PATCH 08/54] Timer improvements for emulated printers --- src/printer/prt_escp.c | 14 ++++++++++++++ src/printer/prt_ps.c | 17 +++++++++++++++++ src/printer/prt_text.c | 17 +++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 41c81e696..1855df380 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1906,6 +1906,13 @@ strobe(uint8_t old, uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); @@ -1940,6 +1947,13 @@ write_ctrl(uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 904ff34ad..b8f3b20b9 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -34,6 +34,7 @@ #include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/prt_devs.h> +#include "cpu.h" #ifdef _WIN32 # define GSDLLAPI __stdcall @@ -341,6 +342,14 @@ ps_strobe(uint8_t old, uint8_t val, void *priv) if (!(val & 0x01) && (old & 0x01)) { process_data(dev); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); @@ -371,6 +380,14 @@ ps_write_ctrl(uint8_t val, void *priv) if (!(val & 0x01) && (dev->ctrl & 0x01)) { process_data(dev); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index 7604d023e..3acccf830 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -63,6 +63,7 @@ #include <86box/lpt.h> #include <86box/printer.h> #include <86box/prt_devs.h> +#include "cpu.h" #define FULL_PAGE 1 /* set if no top/bot margins */ @@ -391,6 +392,14 @@ strobe(uint8_t old, uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev); + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; @@ -429,6 +438,14 @@ write_ctrl(uint8_t val, void *priv) /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; + if (timer_is_enabled(&dev->timeout_timer)) { + timer_disable(&dev->timeout_timer); +#ifdef USE_DYNAREC + if (cpu_use_dynarec) + update_tsc(); +#endif + } + timer_set_delay_u64(&dev->pulse_timer, ISACONST); timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); } From ef977aec456a5f9ef652de5b799f97d4859c6889 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 6 Jul 2025 03:29:36 +0200 Subject: [PATCH 09/54] ALi M5123: Actually set the parallel port DMA channel. --- src/sio/sio_ali5123.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index 436e425d2..e0f676d7c 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -103,6 +103,7 @@ ali5123_lpt_handler(ali5123_t *dev) lpt1_setup(ld_port); } lpt1_irq(lpt_irq); + lpt_port_dma(0, lpt_dma); } static void From 2d4649af8497f29a3cafa64d4482b11b0d6f5a53 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 01:26:18 -0400 Subject: [PATCH 10/54] Cleanups in snd_sb.c --- src/sound/snd_sb.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 14726d358..1aef7d575 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -3481,7 +3481,6 @@ sb_16_compat_init(const device_t *info) music_add_handler(sb_get_music_buffer_sb16_awe32, sb); sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); mpu401_init(sb->mpu, 0, 0, M_UART, (int) (intptr_t) info->local); sb_dsp_set_mpu(&sb->dsp, sb->mpu); @@ -3549,8 +3548,6 @@ sb_awe32_init(UNUSED(const device_t *info)) uint16_t emu_addr = device_get_config_hex16("emu_base"); int onboard_ram = device_get_config_int("onboard_ram"); - memset(sb, 0x00, sizeof(sb_t)); - sb->opl_enabled = device_get_config_int("opl"); if (sb->opl_enabled) fm_driver_get(FM_YMF262, &sb->opl); @@ -3594,7 +3591,6 @@ sb_awe32_init(UNUSED(const device_t *info)) if (mpu_addr) { sb->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); - memset(sb->mpu, 0, sizeof(mpu_t)); mpu401_init(sb->mpu, device_get_config_hex16("base401"), 0, M_UART, device_get_config_int("receive_input401")); } else @@ -4153,7 +4149,7 @@ static const device_config_t sb_config[] = { .spinner = { 0 }, .selection = { { 0 } }, .bios = { { 0 } } - }, + }, { .name = "", .description = "", .type = CONFIG_END } }; @@ -4178,8 +4174,8 @@ static const device_config_t sb15_config[] = { .bios = { { 0 } } }, { - .name = "irq", - .description = "IRQ", + .name = "irq", + .description = "IRQ", .type = CONFIG_SELECTION, .default_string = NULL, .default_int = 7, @@ -4247,8 +4243,8 @@ static const device_config_t sb15_config[] = { static const device_config_t sb2_config[] = { { - .name = "base", - .description = "Address", + .name = "base", + .description = "Address", .type = CONFIG_HEX16, .default_string = NULL, .default_int = 0x220, @@ -4298,7 +4294,7 @@ static const device_config_t sb2_config[] = { .name = "dma", .description = "DMA", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 1, .file_filter = NULL, .spinner = { 0 }, @@ -4367,7 +4363,7 @@ static const device_config_t sb_mcv_config[] = { .name = "dma", .description = "DMA", .type = CONFIG_SELECTION, - .default_string = "", + .default_string = NULL, .default_int = 1, .file_filter = NULL, .spinner = { 0 }, @@ -5343,7 +5339,7 @@ static const device_config_t ess_1688_pnp_config[] = { .name = "control_pc_speaker", .description = "Control PC speaker", .type = CONFIG_BINARY, - .default_string = "", + .default_string = NULL, .default_int = 0, .file_filter = NULL, .spinner = { 0 }, @@ -5354,7 +5350,7 @@ static const device_config_t ess_1688_pnp_config[] = { .name = "receive_input", .description = "Receive MIDI input", .type = CONFIG_BINARY, - .default_string = "", + .default_string = NULL, .default_int = 1, .file_filter = NULL, .spinner = { 0 }, @@ -5365,7 +5361,7 @@ static const device_config_t ess_1688_pnp_config[] = { .name = "receive_input401", .description = "Receive MIDI input (MPU-401)", .type = CONFIG_BINARY, - .default_string = "", + .default_string = NULL, .default_int = 0, .file_filter = NULL, .spinner = { 0 }, From 7ffb65827eaec48b864e4f0c82d7a951dede72b0 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 4 Jul 2025 20:10:20 -0400 Subject: [PATCH 11/54] AWE32 (Non PNP) has a non-PNP gameport --- src/sound/snd_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 1aef7d575..917d321ef 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -3602,7 +3602,7 @@ sb_awe32_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport = gameport_add(&gameport_device); sb->gameport_addr = 0x200; gameport_remap(sb->gameport, sb->gameport_addr); From b0a5a8559422a0f900f2d1a1ea394d324af8f173 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 01:37:28 -0400 Subject: [PATCH 12/54] Remove DMA option from older SB's You couldn't pick any DMA other than 1 --- src/sound/snd_sb.c | 47 +--------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 917d321ef..dd853d2ba 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2864,7 +2864,7 @@ sb_init(UNUSED(const device_t *info)) sb_dsp_init(&sb->dsp, model, SB_SUBTYPE_DEFAULT, sb); sb_dsp_setaddr(&sb->dsp, addr); sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); + sb_dsp_setdma8(&sb->dsp, 1); // SB 1, SB1.5 and 2 don't support DMA3 if (mixer_addr > 0x0000) sb_ct1335_mixer_reset(sb); @@ -4113,21 +4113,6 @@ static const device_config_t sb_config[] = { }, .bios = { { 0 } } }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 1, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "DMA 1", .value = 1 }, - { .description = "DMA 3", .value = 3 }, - { .description = "" } - }, - .bios = { { 0 } } - }, { .name = "opl", .description = "Enable OPL", @@ -4190,21 +4175,6 @@ static const device_config_t sb15_config[] = { }, .bios = { { 0 } } }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 1, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "DMA 1", .value = 1 }, - { .description = "DMA 3", .value = 3 }, - { .description = "" } - }, - .bios = { { 0 } } - }, { .name = "opl", .description = "Enable OPL", @@ -4290,21 +4260,6 @@ static const device_config_t sb2_config[] = { }, .bios = { { 0 } } }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .default_string = NULL, - .default_int = 1, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "DMA 1", .value = 1 }, - { .description = "DMA 3", .value = 3 }, - { .description = "" } - }, - .bios = { { 0 } } - }, { .name = "opl", .description = "Enable OPL", From 8774ff0182cc6badc106d966dd7ae1c810201da1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 01:41:39 -0400 Subject: [PATCH 13/54] Add gameport to SB1, 1.5 and 2 --- src/sound/snd_sb.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index dd853d2ba..9fc04eefa 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2869,6 +2869,12 @@ sb_init(UNUSED(const device_t *info)) if (mixer_addr > 0x0000) sb_ct1335_mixer_reset(sb); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } + /* DSP I/O handler is activated in sb_dsp_setaddr */ if (sb->opl_enabled) { // TODO: See if this applies to the SB1.5 as well @@ -4113,6 +4119,17 @@ static const device_config_t sb_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -4175,6 +4192,17 @@ static const device_config_t sb15_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -4260,6 +4288,17 @@ static const device_config_t sb2_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", From 60dde4dab7b27927672cf87b8f4dd12d7a39caa4 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 09:03:56 -0400 Subject: [PATCH 14/54] Add gameport to MCA Soundblasters --- src/sound/snd_sb.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 9fc04eefa..c60b5cfe0 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -2954,6 +2954,12 @@ sb_mcv_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } + return sb; } @@ -3123,6 +3129,12 @@ sb_pro_mcv_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } + return sb; } @@ -4368,6 +4380,17 @@ static const device_config_t sb_mcv_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", @@ -4468,6 +4491,17 @@ static const device_config_t sb_pro_config[] = { }; static const device_config_t sb_pro_mcv_config[] = { + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "receive_input", .description = "Receive MIDI input", From 43ee3d3e6b7af6a5a67ccc2c380237a8cea19f1e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 09:04:23 -0400 Subject: [PATCH 15/54] Add gameport to Soundblaster Pro v1 and v2 --- src/sound/snd_sb.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index c60b5cfe0..0e67f7c22 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -3042,6 +3042,12 @@ sb_pro_v1_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } + return sb; } @@ -3096,6 +3102,12 @@ sb_pro_v2_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } + return sb; } @@ -4465,6 +4477,17 @@ static const device_config_t sb_pro_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", From 870d06ae8a72a3ed4b6347761b636dc1fdaadf99 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 02:11:11 -0400 Subject: [PATCH 16/54] Allow SB16 (Non-PNP) gameport to be disabled --- src/sound/snd_sb.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 0e67f7c22..345b6346b 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -3231,9 +3231,17 @@ sb_16_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - sb->gameport = gameport_add(&gameport_pnp_device); - sb->gameport_addr = 0x200; - gameport_remap(sb->gameport, sb->gameport_addr); + if (info->local == FM_YMF289B) { + sb->gameport = gameport_add(&gameport_pnp_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } else { + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } + } return sb; } @@ -4622,6 +4630,17 @@ static const device_config_t sb_16_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", From 7ab8987a2be60ec0868810b978fc6ecaf0c2c790 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 01:50:29 -0400 Subject: [PATCH 17/54] Allow AWE32 (Non-PNP) gameport to be disabled --- src/sound/snd_sb.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 345b6346b..d75ee5766 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -3640,9 +3640,11 @@ sb_awe32_init(UNUSED(const device_t *info)) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); - sb->gameport = gameport_add(&gameport_device); - sb->gameport_addr = 0x200; - gameport_remap(sb->gameport, sb->gameport_addr); + if (device_get_config_int("gameport")) { + sb->gameport = gameport_add(&gameport_device); + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, sb->gameport_addr); + } return sb; } @@ -4923,6 +4925,17 @@ static const device_config_t sb_awe32_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "opl", .description = "Enable OPL", From 87892e72d6afec5b3443d9d682c004a3de67b5a1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sun, 6 Jul 2025 02:42:10 -0400 Subject: [PATCH 18/54] Allow ES688/1688 (Non-PNP) gameport to be disabled --- src/sound/snd_sb.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index d75ee5766..e612250b7 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -3906,9 +3906,11 @@ ess_x688_init(UNUSED(const device_t *info)) sb_dsp_set_mpu(&ess->dsp, ess->mpu); } - ess->gameport = gameport_add(&gameport_pnp_device); - ess->gameport_addr = 0x200; - gameport_remap(ess->gameport, ess->gameport_addr); + if (device_get_config_int("gameport")) { + ess->gameport = gameport_add(&gameport_device); + ess->gameport_addr = 0x200; + gameport_remap(ess->gameport, ess->gameport_addr); + } if (ide_base > 0x0000) { device_add(&ide_qua_pnp_device); @@ -5265,6 +5267,17 @@ static const device_config_t ess_688_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "ide_ctrl", .description = "IDE Controller", @@ -5348,6 +5361,17 @@ static const device_config_t ess_1688_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "ide_ctrl", .description = "IDE Controller", From 04ae339ba1190e00d84c1a5b31a1ab875075be17 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Jul 2025 03:07:22 +0200 Subject: [PATCH 19/54] Parallel ports: Fix EPP-related ports handling, appears to fix a reported sound regression. --- src/device/lpt.c | 33 +++++++++++++---------------- src/include/86box/lpt.h | 1 + src/sio/sio_ali5123.c | 46 ++++++++++++++++++++++++++++++++++------- src/sio/sio_pc87306.c | 14 +++++++------ 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/src/device/lpt.c b/src/device/lpt.c index 11afc04f9..4c5578490 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -626,34 +626,29 @@ lpt_set_ext(const int port, const uint8_t ext) void lpt_set_ecp(const int port, const uint8_t ecp) { - if (lpt_ports[port].enabled) { - const uint16_t addr = lpt_ports[port].addr; - lpt_port_setup(port, 0xfff); + if (lpt_ports[port].enabled) lpt_ports[port].ecp = ecp; - lpt_port_setup(port, addr); - } } void lpt_set_epp(const int port, const uint8_t epp) { - if (lpt_ports[port].enabled) { - const uint16_t addr = lpt_ports[port].addr; - lpt_port_setup(port, 0xfff); + if (lpt_ports[port].enabled) lpt_ports[port].epp = epp; - lpt_port_setup(port, addr); - } } void lpt_set_lv2(const int port, const uint8_t lv2) { - if (lpt_ports[port].enabled) { - const uint16_t addr = lpt_ports[port].addr; - lpt_port_setup(port, 0xfff); + if (lpt_ports[port].enabled) lpt_ports[port].lv2 = lv2; - lpt_port_setup(port, addr); - } +} + +void +lpt_set_fifo_threshold(const int port, const int threshold) +{ + if (lpt_ports[port].enabled) + fifo_set_trigger_len(lpt_ports[port].fifo, threshold); } void @@ -778,19 +773,19 @@ void lpt_port_setup(const int i, const uint16_t port) { if (lpt_ports[i].enabled) { - if (lpt_ports[i].addr != 0xffff) { + if ((lpt_ports[i].addr != 0x0000) && (lpt_ports[i].addr != 0xffff)) { io_removehandler(lpt_ports[i].addr, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); io_removehandler(lpt_ports[i].addr + 0x0400, 0x0007, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); } - if (port != 0xffff) { + if ((port != 0x0000) && (port != 0xffff)) { lpt_log("Set handler: %04X-%04X\n", port, port + 0x0003); io_sethandler(port, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); if (lpt_ports[i].epp) - io_sethandler(lpt_ports[i].addr + 0x0003, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); + io_sethandler(port + 0x0003, 0x0005, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); if (lpt_ports[i].ecp || lpt_ports[i].lv2) { io_sethandler(port + 0x0400, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); if (lpt_ports[i].epp) - io_sethandler(lpt_ports[i].addr + 0x0403, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); + io_sethandler(port + 0x0404, 0x0003, lpt_read, NULL, NULL, lpt_write, NULL, NULL, &lpt_ports[i]); } } lpt_ports[i].addr = port; diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index c13d70291..b3e4d070b 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -37,6 +37,7 @@ extern void lpt_set_ext(int port, uint8_t ext); extern void lpt_set_ecp(int port, uint8_t ecp); extern void lpt_set_epp(int port, uint8_t epp); extern void lpt_set_lv2(int port, uint8_t lv2); +extern void lpt_set_fifo_threshold(int port, int threshold); extern void lpt_reset(void); extern void lpt_close(void); extern void lpt_init(void); diff --git a/src/sio/sio_ali5123.c b/src/sio/sio_ali5123.c index e0f676d7c..7dc522b30 100644 --- a/src/sio/sio_ali5123.c +++ b/src/sio/sio_ali5123.c @@ -81,25 +81,57 @@ ali5123_fdc_handler(ali5123_t *dev) static void ali5123_lpt_handler(ali5123_t *dev) { - uint16_t ld_port = 0; + uint16_t ld_port = 0x0000; + uint16_t mask = 0xfffc; uint8_t global_enable = !(dev->regs[0x22] & (1 << 3)); uint8_t local_enable = !!dev->ld_regs[3][0x30]; uint8_t lpt_irq = dev->ld_regs[3][0x70]; uint8_t lpt_dma = dev->ld_regs[3][0x74]; + uint8_t lpt_mode = dev->ld_regs[3][0xf0] & 0x07; if (lpt_irq > 15) lpt_irq = 0xff; - if (lpt_dma == 4) + if (lpt_dma >= 4) lpt_dma = 0xff; lpt1_remove(); - lpt_set_epp(0, !!(dev->ld_regs[3][0xf0] & 0x01)); - lpt_set_ecp(0, !!(dev->ld_regs[3][0xf0] & 0x02)); - lpt_set_ext(0, !(dev->ld_regs[3][0xf0] & 0x04) || !!(dev->ld_regs[3][0xf1] & 0x80)); + lpt_set_fifo_threshold(0, (dev->ld_regs[3][0xf0] & 0x78) >> 3); + if ((lpt_mode == 0x04) && (dev->ld_regs[3][0xf1] & 0x80)) + lpt_mode = 0x00; + switch (lpt_mode) { + default: + case 0x04: + lpt_set_epp(0, 0); + lpt_set_ecp(0, 0); + lpt_set_ext(0, 0); + break; + case 0x00: + lpt_set_epp(0, 0); + lpt_set_ecp(0, 0); + lpt_set_ext(0, 1); + break; + case 0x01: case 0x05: + mask = 0xfff8; + lpt_set_epp(0, 1); + lpt_set_ecp(0, 0); + lpt_set_ext(0, 0); + break; + case 0x02: + lpt_set_epp(0, 0); + lpt_set_ecp(0, 1); + lpt_set_ext(0, 0); + break; + case 0x03: case 0x07: + mask = 0xfff8; + lpt_set_epp(0, 1); + lpt_set_ecp(0, 1); + lpt_set_ext(0, 0); + break; + } if (global_enable && local_enable) { - ld_port = make_port(dev, 3) & 0xFFFC; - if ((ld_port >= 0x0100) && (ld_port <= 0x0FFC)) + ld_port = (make_port(dev, 3) & 0xfffc) & mask; + if ((ld_port >= 0x0100) && (ld_port <= (0x0ffc & mask))) lpt1_setup(ld_port); } lpt1_irq(lpt_irq); diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index e42c48ab4..5a0a8798a 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -123,6 +123,8 @@ lpt1_handler(pc87306_t *dev) uint8_t lpt_irq = LPT2_IRQ; uint8_t lpt_dma = ((dev->regs[0x18] & 0x06) >> 1); + lpt1_remove(); + if (lpt_dma == 0x00) lpt_dma = 0xff; @@ -157,17 +159,17 @@ lpt1_handler(pc87306_t *dev) if (dev->regs[0x1b] & 0x10) lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5; + lpt_set_ext(0, !!(dev->regs[0x02] & 0x80)); + + lpt_set_epp(0, !!(dev->regs[0x04] & 0x01)); + lpt_set_ecp(0, !!(dev->regs[0x04] & 0x04)); + if (lpt_port) lpt1_setup(lpt_port); lpt1_irq(lpt_irq); lpt_port_dma(0, lpt_dma); - - lpt_set_ext(0, !!(dev->regs[0x02] & 0x80)); - - lpt_set_epp(0, !!(dev->regs[0x04] & 0x01)); - lpt_set_ecp(0, !!(dev->regs[0x04] & 0x04)); } static void @@ -386,7 +388,7 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) if (valxor & 0x70) { lpt1_remove(); if (!(val & 0x40)) - dev->regs[0x19] = 0xEF; + dev->regs[0x19] = 0xef; if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) lpt1_handler(dev); } From 1b735084a41eac2182c7a7e99b348319ac630cd3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 7 Jul 2025 17:44:47 +0600 Subject: [PATCH 20/54] Always load "opengl32.dll" from application directory if it exists --- src/qt/qt_main.cpp | 12 ++++++++++++ src/qt/qt_platform.cpp | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index eb7d6ac44..da57bcf80 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -102,6 +102,8 @@ bool cpu_thread_running = false; void qt_set_sequence_auto_mnemonic(bool b); #ifdef Q_OS_WINDOWS +bool acp_utf8 = false; + static void keyboard_getkeymap() { @@ -515,6 +517,13 @@ extern bool windows_is_light_theme(); int main(int argc, char *argv[]) { +#ifdef Q_OS_WINDOWS + /* Check if Windows supports UTF-8 */ + if (GetACP() == CP_UTF8) + acp_utf8 = 1; + else + acp_utf8 = 0; +#endif #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); @@ -530,6 +539,9 @@ main(int argc, char *argv[]) #ifdef Q_OS_WINDOWS Q_INIT_RESOURCE(darkstyle); + if (QFile(QApplication::applicationDirPath() + "/opengl32.dll").exists()) { + qputenv("QT_OPENGL_DLL", QFileInfo(QApplication::applicationDirPath() + "/opengl32.dll").absoluteFilePath().toUtf8()); + } QApplication::setAttribute(Qt::AA_NativeWindows); if (!windows_is_light_theme()) { diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 8677a6a91..a2c0bc410 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -177,14 +177,28 @@ do_stop(void) #endif } +extern bool acp_utf8; void plat_get_exe_name(char *s, int size) { +#ifdef Q_OS_WINDOWS + wchar_t *temp; + + if (acp_utf8) + GetModuleFileNameA(NULL, s, size); + else { + temp = (wchar_t*)calloc(size, sizeof(wchar_t)); + GetModuleFileNameW(NULL, temp, size); + c16stombs(s, (uint16_t*)temp, size); + free(temp); + } +#else QByteArray exepath_temp = QCoreApplication::applicationDirPath().toLocal8Bit(); memcpy(s, exepath_temp.data(), std::min((qsizetype) exepath_temp.size(), (qsizetype) size)); path_slash(s); +#endif } uint32_t From 63e5303b9e6880ff4d66c416550267a54b64c2a8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 8 Jul 2025 00:56:52 +0600 Subject: [PATCH 21/54] Don't draw blank screens out of bounds --- src/video/vid_svga_render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 0c3252414..b3a5c0192 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -58,7 +58,7 @@ svga_render_null(svga_t *svga) void svga_render_blank(svga_t *svga) { - if ((svga->displine + svga->y_add) < 0) + if ((svga->displine + svga->y_add) < 0 || (svga->displine + svga->y_add) >= 2048) return; if (svga->firstline_draw == 2000) From b0bcbc8bc73b20ba93aa988486fdf99b87b15304 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 8 Jul 2025 03:57:07 +0200 Subject: [PATCH 22/54] Moved the Micronics 09-00021 machine init functions to the correct files and gave them port_92_device, fixes #5754. --- src/machine/m_at_286_386sx.c | 40 ---------------------------------- src/machine/m_at_386dx_486.c | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index e91b9bcf5..f97797fc1 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -391,46 +391,6 @@ machine_at_tuliptc7_init(const machine_t *model) return ret; } -int -machine_at_micronics386_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", - "roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_init(model); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - -int -machine_at_micronics386px_init(const machine_t *model) -{ - int ret; - - ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-LO.BIN", - "roms/machines/micronics386/386-Micronics-09-00021-HI.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_init(model); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - return ret; -} - static void machine_at_scat_init(const machine_t *model, int is_v4, int is_ami) { diff --git a/src/machine/m_at_386dx_486.c b/src/machine/m_at_386dx_486.c index eb91f300c..169296529 100644 --- a/src/machine/m_at_386dx_486.c +++ b/src/machine/m_at_386dx_486.c @@ -2919,3 +2919,45 @@ machine_at_cougar_init(const machine_t *model) return ret; } + +int +machine_at_micronics386_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-EVEN.BIN", + "roms/machines/micronics386/386-Micronics-09-00021-ODD.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + device_add(&port_92_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + +int +machine_at_micronics386px_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/micronics386/386-Micronics-09-00021-LO.BIN", + "roms/machines/micronics386/386-Micronics-09-00021-HI.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_init(model); + device_add(&port_92_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} From a2354599c6bd35f5973d93249619130a6bcfb1f7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 8 Jul 2025 05:08:23 +0200 Subject: [PATCH 23/54] Vx0: Always resume from interrupt on HLT, even if I_FLAG is not set. --- src/cpu/808x.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 2e24d3c49..af95b6316 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1226,21 +1226,23 @@ custom_nmi(void) } static int -irq_pending(void) +irq_pending(int nec_hlt) { uint8_t temp; + int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; - temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint); + temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || (i_flag && pic.int_pending && !noint); return temp; } static void -check_interrupts(void) +check_interrupts(int nec_hlt) { int temp; + int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; - if (irq_pending()) { + if (irq_pending(nec_hlt)) { if ((cpu_state.flags & T_FLAG) && !noint) { interrupt(1); return; @@ -1256,7 +1258,7 @@ check_interrupts(void) #endif return; } - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) { + if (i_flag && pic.int_pending && !noint) { repeating = 0; completed = 1; ovr_seg = NULL; @@ -1289,7 +1291,7 @@ rep_action(int bits) return 0; wait_cycs(2, 0); t = CX; - if (irq_pending() && (repeating != 0)) { + if (irq_pending(0) && (repeating != 0)) { access(71, bits); pfq_clear(); if (is_nec && (ovr_seg != NULL)) @@ -3008,9 +3010,9 @@ execx86(int cycs) wait_cycs(2, 0); wait_cycs(5, 0); #ifdef NO_HACK - if (irq_pending()) { + if (irq_pending(0)) { wait_cycs(7, 0); - check_interrupts(); + check_interrupts(0); } else { repeating = 1; completed = 0; @@ -3018,7 +3020,7 @@ execx86(int cycs) } #else wait_cycs(7, 0); - check_interrupts(); + check_interrupts(0); #endif break; case 0x9C: /*PUSHF*/ @@ -3647,9 +3649,9 @@ execx86(int cycs) pfq_clear(); } wait_cycs(1, 0); - if (irq_pending()) { + if (irq_pending(is_nec)) { wait_cycs(cycles & 1, 0); - check_interrupts(); + check_interrupts(is_nec); } else { repeating = 1; completed = 0; @@ -3848,7 +3850,7 @@ exec_completed: if (in_lock) clear_lock = 1; clock_end(); - check_interrupts(); + check_interrupts(0); if (noint) noint = 0; From 42c007770357922039f5c80b87fabd5bda871465 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 8 Jul 2025 05:21:44 +0200 Subject: [PATCH 24/54] 808x: Suspend trap for 1 instruction after POPF and do not do it after IRET. --- src/cpu/808x.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index af95b6316..edab16567 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1243,7 +1243,7 @@ check_interrupts(int nec_hlt) int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; if (irq_pending(nec_hlt)) { - if ((cpu_state.flags & T_FLAG) && !noint) { + if ((cpu_state.flags & T_FLAG) && !(noint & 1)) { interrupt(1); return; } @@ -3031,16 +3031,19 @@ execx86(int cycs) tempw = (cpu_state.flags & 0x0fd7) | 0xf000; push(&tempw); break; - case 0x9D: /*POPF*/ + case 0x9D: { /*POPF*/ + uint16_t old_flags = cpu_state.flags; access(25, 16); if (is_nec && cpu_md_write_disable) cpu_state.flags = pop() | 0x8002; else cpu_state.flags = pop() | 0x0002; wait_cycs(1, 0); + if ((old_flags ^ cpu_state.flags) & T_FLAG) + noint = 1; sync_to_i8080(); break; - case 0x9E: /*SAHF*/ + } case 0x9E: /*SAHF*/ wait_cycs(1, 0); cpu_state.flags = (cpu_state.flags & 0xff02) | AH; wait_cycs(2, 0); @@ -3309,7 +3312,7 @@ execx86(int cycs) else cpu_state.flags = pop() | 0x0002; wait_cycs(5, 0); - noint = 1; + noint = 2; nmi_enable = 1; if (is_nec && !(cpu_state.flags & MD_FLAG)) sync_to_i8080(); From 773ebf62545c19afd87a5963de406e466559bee0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 8 Jul 2025 05:59:04 +0200 Subject: [PATCH 25/54] Fix V20/V30 CPU speeds. --- src/cpu/cpu_table.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 8524306dc..db8c89ebb 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -688,6 +688,23 @@ const cpu_family_t cpu_families[] = { .cache_write_cycles = 0, .atclk_div = 1 }, + { + .name = "8", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, { .name = "10", .cpu_type = CPU_V20, @@ -911,10 +928,10 @@ const cpu_family_t cpu_families[] = { .internal_name = "necv30", .cpus = (const CPU[]) { { - .name = "5", + .name = "7.16", .cpu_type = CPU_V30, .fpus = fpus_80186, - .rspeed = 5000000, + .rspeed = 7159092, .multi = 1, .voltage = 5000, .edx_reset = 0, @@ -944,6 +961,23 @@ const cpu_family_t cpu_families[] = { .cache_write_cycles = 0, .atclk_div = 1 }, + { + .name = "9.54", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, { .name = "10", .cpu_type = CPU_V30, From 283ba780905bdc2aabbbce688517606b07a18226 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 8 Jul 2025 09:19:02 +0200 Subject: [PATCH 26/54] Slow PIT: convert BCD counts to binary when passing them to the speaker. --- src/pit.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/pit.c b/src/pit.c index a283d1205..15de2ba86 100644 --- a/src/pit.c +++ b/src/pit.c @@ -358,8 +358,18 @@ ctr_load(ctr_t *ctr) else ctr_set_state_1(ctr); - if (ctr->load_func != NULL) - ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); + if (ctr->load_func != NULL) { + uint32_t count = ctr->l ? ctr->l : 0x10000; + if (ctr->bcd) { + uint32_t bcd_count = (((count >> 16) & 0xf) * 10000) | + (((count >> 12) & 0xf) * 1000 ) | + (((count >> 8 ) & 0xf) * 100 ) | + (((count >> 4 ) & 0xf) * 10 ) | + (count & 0xf); + ctr->load_func(ctr->m, bcd_count); + } else + ctr->load_func(ctr->m, ctr->l ? ctr->l : 0x10000); + } pit_log("Counter loaded, state = %i, gate = %i, latch = %i\n", ctr->state, ctr->gate, ctr->latch); } From 4680d758a622f2d4b5284bd73ed51e31234b5aa4 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 8 Jul 2025 15:55:50 +0600 Subject: [PATCH 27/54] 1ms --- src/86box.c | 4 ++-- src/qt/qt_main.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/86box.c b/src/86box.c index ae58aca03..74b95aeae 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1714,7 +1714,7 @@ pc_run(void) /* Run a block of code. */ startblit(); - cpu_exec((int32_t) cpu_s->rspeed / 100); + cpu_exec((int32_t) cpu_s->rspeed / 1000); ack_pause(); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ if (gdbstub_step == GDBSTUB_EXEC) { @@ -1729,7 +1729,7 @@ pc_run(void) /* Done with this frame, update statistics. */ framecount++; - if (++framecountx >= 100) { + if (++framecountx >= 1000) { framecountx = 0; frames = 0; } diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index da57bcf80..077e92641 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -448,15 +448,15 @@ main_thread_fn() const uint64_t new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; + drawits = 1; else #endif drawits += static_cast(new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ - drawits -= 10; - if (drawits > 50) + drawits -= 1; + if (drawits > 500) drawits = 0; #ifdef USE_INSTRUMENT @@ -475,7 +475,7 @@ main_thread_fn() } #endif /* Every 200 frames we save the machine status. */ - if (++frames >= 200 && nvr_dosave) { + if (++frames >= 2000 && nvr_dosave) { qt_nvr_save(); nvr_dosave = 0; frames = 0; @@ -493,7 +493,7 @@ main_thread_fn() if (dopause) ack_pause(); - plat_delay_ms(1); + //plat_delay_ms(1); } } From ddea070faae91a6573395e2b16c3ee18d8941a95 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 8 Jul 2025 16:51:53 +0600 Subject: [PATCH 28/54] Fix cycle period of dynarec --- src/cpu/386_dynarec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index fd6285057..dfad67020 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -739,7 +739,7 @@ exec386_dynarec(int32_t cycs) uint64_t oldtsc; uint64_t delta; - int32_t cyc_period = cycs / 2000; /*5us*/ + int32_t cyc_period = cycs / 200; /*5us*/ # ifdef USE_ACYCS acycs = 0; From 7b6d726c18cb82fb980ebd69cce5700e4353f5ae Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 9 Jul 2025 01:14:08 +0600 Subject: [PATCH 29/54] Restore 1 ms sleep --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 077e92641..57c6a3996 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -493,7 +493,7 @@ main_thread_fn() if (dopause) ack_pause(); - //plat_delay_ms(1); + plat_delay_ms(1); } } From b45d7962185f2ac0a964790e4e2aae1d67a54fc0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 9 Jul 2025 02:11:55 +0600 Subject: [PATCH 30/54] Allow up to 50 missed CPU frames instead of 500 --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 57c6a3996..73c501abf 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -456,7 +456,7 @@ main_thread_fn() if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ drawits -= 1; - if (drawits > 500) + if (drawits > 50) drawits = 0; #ifdef USE_INSTRUMENT From bec9a8ecfb083975683be663f090fad16acf28b3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 8 Jul 2025 23:38:29 +0200 Subject: [PATCH 31/54] SDL Joystick: Make thread hinting Windows-only, fixes #5762. --- src/qt/sdl_joystick.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index 83a2a67b1..ea3720eea 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -45,8 +45,10 @@ static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; void joystick_init(void) { +#ifdef _WIN32 /* This is needed for SDL's Windows raw input backend to work properly without SDL video. */ SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); +#endif if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { return; From e662f27f5f71f8d30b954393d3216e15c9ffbc7d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 9 Jul 2025 04:08:18 +0200 Subject: [PATCH 32/54] Slow PIT: Fix mode 3 (square wave) operation, fixes Night Hunter sound effects, fixes #4704. --- src/pit.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pit.c b/src/pit.c index 15de2ba86..8fdb69c3e 100644 --- a/src/pit.c +++ b/src/pit.c @@ -247,7 +247,7 @@ ctr_tick(ctr_t *ctr, void *priv) ctr_decrease_count(ctr); } else ctr->count -= (ctr->newcount ? 1 : 2); - if (ctr->count < 0) { + if (ctr->count == 0) { ctr_set_out(ctr, 0, pit); ctr_load_count(ctr); ctr->state = 3; @@ -266,7 +266,7 @@ ctr_tick(ctr_t *ctr, void *priv) ctr_decrease_count(ctr); } else ctr->count -= (ctr->newcount ? 3 : 2); - if (ctr->count < 0) { + if (ctr->count == 0) { ctr_set_out(ctr, 1, pit); ctr_load_count(ctr); ctr->state = 2; @@ -334,10 +334,11 @@ ctr_set_state_1(ctr_t *ctr) { uint8_t mode = (ctr->m & 0x03); int do_reload = !!ctr->incomplete || (mode == 0) || (ctr->state == 0); + int disables_counting = (mode != 1) && !ctr->gate; ctr->incomplete = 0; - if (do_reload) + if (do_reload && !disables_counting) ctr->state = 1 + ((mode == 1) << 2); } From b01f3124722d55bacb038cfddb886fdfe1ca7877 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 9 Jul 2025 04:38:55 +0200 Subject: [PATCH 33/54] Slow PIT: Fix a regression introduced in the previous commit and the logging. --- src/pit.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pit.c b/src/pit.c index 8fdb69c3e..b99fed799 100644 --- a/src/pit.c +++ b/src/pit.c @@ -334,11 +334,10 @@ ctr_set_state_1(ctr_t *ctr) { uint8_t mode = (ctr->m & 0x03); int do_reload = !!ctr->incomplete || (mode == 0) || (ctr->state == 0); - int disables_counting = (mode != 1) && !ctr->gate; - + ctr->incomplete = 0; - if (do_reload && !disables_counting) + if (do_reload) ctr->state = 1 + ((mode == 1) << 2); } @@ -551,7 +550,8 @@ pit_write(uint16_t addr, uint8_t val, void *priv) ctr_t *ctr; if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { - pit_log("[%04X:%08X] pit_write(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); + pit_log("[%04X:%08X] pit_write(%04X, %02X, %016" PRIX64 ")\n", + CS, cpu_state.pc, addr, val, (uint64_t) (uintptr_t) priv); } switch (addr & 3) { @@ -799,7 +799,8 @@ pit_read(uint16_t addr, void *priv) } if ((dev->flags & (PIT_8254 | PIT_EXT_IO))) { - pit_log("[%04X:%08X] pit_read(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + pit_log("[%04X:%08X] pit_read(%04X, %016" PRIX64 ") = %02X\n", + CS, cpu_state.pc, addr, (uint64_t) (uintptr_t) priv, ret); } return ret; From c648b5cff115f5c11e3eb4cf4ad777e04391bf82 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 9 Jul 2025 05:15:29 +0200 Subject: [PATCH 34/54] Attempt to fix compilation with GCC 9.4.0 on Linux Mint 20.3. --- src/qt/qt_vmmanager_main.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp index c3c541b4f..11381ec1a 100644 --- a/src/qt/qt_vmmanager_main.hpp +++ b/src/qt/qt_vmmanager_main.hpp @@ -68,7 +68,11 @@ public slots: void shutdownForceButtonPressed() const; void searchSystems(const QString &text) const; void newMachineWizard(); +#ifdef _WIN32 void addNewSystem(const QString &name, const QString &dir, const QString &configFile = {}); +#else + void addNewSystem(const QString &name, const QString &dir, const QString &configFile); +#endif [[nodiscard]] QStringList getSearchCompletionList() const; void modelDataChange(); void onPreferencesUpdated(); From c99f4c0db8ab5547b25651022fe30aa2b068fc92 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 9 Jul 2025 07:35:36 +0200 Subject: [PATCH 35/54] PC Speaker: assume 256 counts needed for the speaker to go from off to on instead of 64, improves PC speaker quality and fixes speech in Three Stooges, fixes #4763. --- src/sound/snd_speaker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 0537cd09a..063554875 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -56,7 +56,7 @@ speaker_update(void) int32_t val; double amplitude; - amplitude = ((speaker_count / 64.0) * 10240.0) - 5120.0; + amplitude = ((speaker_count / 256.0) * 10240.0) - 5120.0; if (amplitude > 5120.0) amplitude = 5120.0; From 18fea3383313294866dc83ce6727624c3ebfeb08 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 9 Jul 2025 08:42:42 +0200 Subject: [PATCH 36/54] VM Manager: Do not use [[nodiscard]] when compiling with GCC < 11, actually fixes #5707. --- src/qt/qt_vmmanager_main.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp index 11381ec1a..51ad6dc28 100644 --- a/src/qt/qt_vmmanager_main.hpp +++ b/src/qt/qt_vmmanager_main.hpp @@ -68,12 +68,12 @@ public slots: void shutdownForceButtonPressed() const; void searchSystems(const QString &text) const; void newMachineWizard(); -#ifdef _WIN32 void addNewSystem(const QString &name, const QString &dir, const QString &configFile = {}); -#else - void addNewSystem(const QString &name, const QString &dir, const QString &configFile); -#endif +#if __GNUC__ >= 11 [[nodiscard]] QStringList getSearchCompletionList() const; +#else + QStringList getSearchCompletionList() const; +#endif void modelDataChange(); void onPreferencesUpdated(); From 916533499ae30e819fc32718f6a4b15c0b33777b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 9 Jul 2025 12:59:16 +0600 Subject: [PATCH 37/54] Add 10ms interval option (not exposed yet to UI) Fix percentage counter --- src/86box.c | 17 +++++++++-------- src/config.c | 6 ++++++ src/cpu/386_dynarec.c | 2 +- src/include/86box/86box.h | 1 + src/qt/qt_main.cpp | 8 ++++---- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/86box.c b/src/86box.c index 74b95aeae..8b57e4b90 100644 --- a/src/86box.c +++ b/src/86box.c @@ -217,6 +217,7 @@ int test_mode = 0; /* (C) Test mo char uuid[MAX_UUID_LEN] = { '\0' }; /* (C) UUID or machine identifier */ int sound_muted = 0; /* (C) Is sound muted? */ int inhibit_multimedia_keys; /* (C) Inhibit multimedia keys on Windows. */ +int force_10ms; /* (C) Force 10ms CPU frame intervals. */ int other_ide_present = 0; /* IDE controllers from non-IDE cards are present */ @@ -1592,19 +1593,19 @@ update_mouse_msg(void) *(wcp - 1) = L'\0'; mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%.1lf%%%% - %ls", plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%.1lf%%%% - %ls", (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #else - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%.1lf%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%.1lf%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", + swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%.1lf%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif } @@ -1714,7 +1715,7 @@ pc_run(void) /* Run a block of code. */ startblit(); - cpu_exec((int32_t) cpu_s->rspeed / 1000); + cpu_exec((int32_t) cpu_s->rspeed / (force_10ms ? 100 : 1000)); ack_pause(); #ifdef USE_GDBSTUB /* avoid a KBC FIFO overflow when CPU emulation is stalled */ if (gdbstub_step == GDBSTUB_EXEC) { @@ -1729,14 +1730,14 @@ pc_run(void) /* Done with this frame, update statistics. */ framecount++; - if (++framecountx >= 1000) { + if (++framecountx >= (force_10ms ? 100 : 1000)) { framecountx = 0; frames = 0; } if (title_update) { mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture; - swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps); + swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], (double)fps / (force_10ms ? 1. : 10.)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); diff --git a/src/config.c b/src/config.c index 272ca43b7..76abbae23 100644 --- a/src/config.c +++ b/src/config.c @@ -144,6 +144,8 @@ load_general(void) video_grayscale = ini_section_get_int(cat, "video_grayscale", 0); video_graytype = ini_section_get_int(cat, "video_graytype", 0); + force_10ms = !!ini_section_get_int(cat, "force_10ms", 0); + rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); @@ -1947,6 +1949,10 @@ save_general(void) const char *va_name; + ini_section_set_int(cat, "force_10ms", force_10ms); + if (force_10ms == 0) + ini_section_delete_var(cat, "force_10ms"); + ini_section_set_int(cat, "inhibit_multimedia_keys", inhibit_multimedia_keys); if (inhibit_multimedia_keys == 0) ini_section_delete_var(cat, "inhibit_multimedia_keys"); diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index dfad67020..23f3f1e35 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -739,7 +739,7 @@ exec386_dynarec(int32_t cycs) uint64_t oldtsc; uint64_t delta; - int32_t cyc_period = cycs / 200; /*5us*/ + int32_t cyc_period = cycs / (force_10ms ? 2000 : 200); /*5us*/ # ifdef USE_ACYCS acycs = 0; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index e572d670b..bba99b555 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -154,6 +154,7 @@ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ extern int enable_discord; /* (C) enable Discord integration */ +extern int force_10ms; /* (C) force 10ms CPU frame interval */ extern int other_ide_present; /* IDE controllers from non-IDE cards are present */ extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */ diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 73c501abf..1a1f71acb 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -448,14 +448,14 @@ main_thread_fn() const uint64_t new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) - drawits = 1; + drawits = force_10ms ? 10 : 1; else #endif drawits += static_cast(new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ - drawits -= 1; + drawits -= force_10ms ? 10 : 1; if (drawits > 50) drawits = 0; @@ -474,8 +474,8 @@ main_thread_fn() break; } #endif - /* Every 200 frames we save the machine status. */ - if (++frames >= 2000 && nvr_dosave) { + /* Every 2 emulated seconds we save the machine status. */ + if (++frames >= (force_10ms ? 200 : 2000) && nvr_dosave) { qt_nvr_save(); nvr_dosave = 0; frames = 0; From b2f99d72079542de421c4f2770d4e5a5b813bf7f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 9 Jul 2025 13:36:57 +0600 Subject: [PATCH 38/54] Add CPU frame size option --- src/qt/qt_settingsmachine.cpp | 16 ++++ src/qt/qt_settingsmachine.hpp | 4 + src/qt/qt_settingsmachine.ui | 138 ++++++++++++++++++++++------------ 3 files changed, 111 insertions(+), 47 deletions(-) diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index fb5576f69..0063ac727 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -117,6 +117,9 @@ SettingsMachine::SettingsMachine(QWidget *parent) ui->comboBoxMachineType->setCurrentIndex(-1); ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); + ui->radioButtonLargerFrames->setChecked(force_10ms); + ui->radioButtonSmallerFrames->setChecked(!force_10ms); + #ifndef USE_DYNAREC ui->checkBoxDynamicRecompiler->setEnabled(false); ui->checkBoxDynamicRecompiler->setVisible(false); @@ -137,6 +140,7 @@ SettingsMachine::save() fpu_type = ui->comboBoxFPU->currentData().toInt(); cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; fpu_softfloat = ui->checkBoxFPUSoftfloat->isChecked() ? 1 : 0; + force_10ms = ui->radioButtonLargerFrames->isChecked() ? 1 : 0; int64_t temp_mem_size; if (machine_get_ram_granularity(machine) < 1024) @@ -359,3 +363,15 @@ void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { ui->softFloatWarningText->setVisible(false); } } + +void SettingsMachine::on_radioButtonSmallerFrames_clicked() +{ + ui->radioButtonLargerFrames->setChecked(false); +} + + +void SettingsMachine::on_radioButtonLargerFrames_clicked() +{ + ui->radioButtonSmallerFrames->setChecked(false); +} + diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index 864894447..36ece7f18 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -28,6 +28,10 @@ private slots: void on_comboBoxMachineType_currentIndexChanged(int index); void on_checkBoxFPUSoftfloat_stateChanged(int state); + void on_radioButtonSmallerFrames_clicked(); + + void on_radioButtonLargerFrames_clicked(); + private: Ui::SettingsMachine *ui; }; diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index e3b3cdbde..0cd15e749 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -41,7 +41,6 @@ 0 - @@ -49,7 +48,6 @@ - @@ -57,7 +55,6 @@ - @@ -65,7 +62,6 @@ - @@ -73,7 +69,6 @@ - @@ -84,7 +79,6 @@ - @@ -92,7 +86,6 @@ - @@ -100,7 +93,6 @@ - @@ -129,18 +121,16 @@ - Frequency: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - @@ -157,7 +147,6 @@ - @@ -165,7 +154,6 @@ - @@ -173,7 +161,6 @@ - @@ -196,7 +183,6 @@ - @@ -213,7 +199,6 @@ - @@ -268,7 +253,6 @@ - @@ -286,7 +270,6 @@ - @@ -302,7 +285,6 @@ - @@ -310,7 +292,6 @@ - @@ -321,7 +302,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -333,39 +314,102 @@ - - - - - 0 - 0 - - - - Time synchronization - - - - - - Disabled + + + + + + + 0 + 0 + + + Time synchronization + + + + + + Disabled + + + + + + + Enabled (UTC) + + + + + + + Enabled (local time) + + + + - - - - Enabled (local time) + + + + Qt::Orientation::Horizontal + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + CPU frame size + + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + + + + + + Larger frames (less smooth) + + + + + + + Smaller frames (smoother) + + + + - - - - Enabled (UTC) + + + + Qt::Orientation::Vertical - + + + 20 + 40 + + + @@ -373,7 +417,7 @@ - Qt::Vertical + Qt::Orientation::Vertical From 16f15ed53ea83a8ea560ce924e3388ee25cc0885 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 9 Jul 2025 16:45:11 +0600 Subject: [PATCH 39/54] Use integer instead of float for percentage calculations --- src/86box.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/86box.c b/src/86box.c index 8b57e4b90..277d842b4 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1593,19 +1593,19 @@ update_mouse_msg(void) *(wcp - 1) = L'\0'; mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); #ifdef _WIN32 - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%.1lf%%%% - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i.%%i%%%% - %ls", plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%.1lf%%%% - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls", (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #else - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%.1lf%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%.1lf%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%.1lf%%%% - %ls - %ls/%ls", + swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); #endif } @@ -1737,7 +1737,7 @@ pc_run(void) if (title_update) { mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture; - swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], (double)fps / (force_10ms ? 1. : 10.)); + swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); From 1a18bf58acfc2e32c139c2b1e7440af2fd442ee3 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 9 Jul 2025 17:07:33 +0600 Subject: [PATCH 40/54] Make emulator thread time critical if possible on Windows to reduce fluctuations --- src/qt/qt_main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 1a1f71acb..d02ed6b67 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -437,6 +437,9 @@ main_thread_fn() int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); +#ifdef _WIN32 + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); +#endif plat_set_thread_name(nullptr, "main_thread_fn"); framecountx = 0; // title_update = 1; From eea13448db04ae901034a0bdb5062e6404b32e43 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 9 Jul 2025 21:34:59 +0200 Subject: [PATCH 41/54] Actually fix Loopback interrupt. Fixes Netware related sessions with the ne2000 and possibly other dp8390-based cards. --- src/include/86box/net_dp8390.h | 98 +++++++++++++++++----------------- src/network/net_3c503.c | 1 + src/network/net_dp8390.c | 19 ++++--- src/network/net_ne2000.c | 7 +-- src/network/net_wd8003.c | 1 + 5 files changed, 64 insertions(+), 62 deletions(-) diff --git a/src/include/86box/net_dp8390.h b/src/include/86box/net_dp8390.h index 553366808..0b1cc45f5 100644 --- a/src/include/86box/net_dp8390.h +++ b/src/include/86box/net_dp8390.h @@ -41,89 +41,89 @@ typedef struct dp8390_t { /* Command Register - 00h read/write */ struct CR_t { - int stop; /* STP - Software Reset command */ - int start; /* START - start the NIC */ - int tx_packet; /* TXP - initiate packet transmission */ + bool stop; /* STP - Software Reset command */ + bool start; /* START - start the NIC */ + bool tx_packet; /* TXP - initiate packet transmission */ uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ uint8_t pgsel; /* PS0,PS1 - Page select */ } CR; /* Interrupt Status Register - 07h read/write */ struct ISR_t { - int pkt_rx; /* PRX - packet received with no errors */ - int pkt_tx; /* PTX - packet txed with no errors */ - int rx_err; /* RXE - packet rxed with 1 or more errors */ - int tx_err; /* TXE - packet txed " " " " " */ - int overwrite; /* OVW - rx buffer resources exhausted */ - int cnt_oflow; /* CNT - network tally counter MSB's set */ - int rdma_done; /* RDC - remote DMA complete */ - int reset; /* RST - reset status */ + bool pkt_rx; /* PRX - packet received with no errors */ + bool pkt_tx; /* PTX - packet txed with no errors */ + bool rx_err; /* RXE - packet rxed with 1 or more errors */ + bool tx_err; /* TXE - packet txed " " " " " */ + bool overwrite; /* OVW - rx buffer resources exhausted */ + bool cnt_oflow; /* CNT - network tally counter MSB's set */ + bool rdma_done; /* RDC - remote DMA complete */ + bool reset; /* RST - reset status */ } ISR; /* Interrupt Mask Register - 0fh write */ struct IMR_t { - int rx_inte; /* PRXE - packet rx interrupt enable */ - int tx_inte; /* PTXE - packet tx interrput enable */ - int rxerr_inte; /* RXEE - rx error interrupt enable */ - int txerr_inte; /* TXEE - tx error interrupt enable */ - int overw_inte; /* OVWE - overwrite warn int enable */ - int cofl_inte; /* CNTE - counter o'flow int enable */ - int rdma_inte; /* RDCE - remote DMA complete int enable */ - int reserved; /* D7 - reserved */ + bool rx_inte; /* PRXE - packet rx interrupt enable */ + bool tx_inte; /* PTXE - packet tx interrput enable */ + bool rxerr_inte; /* RXEE - rx error interrupt enable */ + bool txerr_inte; /* TXEE - tx error interrupt enable */ + bool overw_inte; /* OVWE - overwrite warn int enable */ + bool cofl_inte; /* CNTE - counter o'flow int enable */ + bool rdma_inte; /* RDCE - remote DMA complete int enable */ + bool reserved; /* D7 - reserved */ } IMR; /* Data Configuration Register - 0eh write */ struct DCR_t { - int wdsize; /* WTS - 8/16-bit select */ - int endian; /* BOS - byte-order select */ - int longaddr; /* LAS - long-address select */ - int loop; /* LS - loopback select */ - int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ + bool wdsize; /* WTS - 8/16-bit select */ + bool endian; /* BOS - byte-order select */ + bool longaddr; /* LAS - long-address select */ + bool loop; /* LS - loopback select */ + bool auto_rx; /* AR - auto-remove rx pkts with remote DMA */ uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ } DCR; /* Transmit Configuration Register - 0dh write */ struct TCR_t { - int crc_disable; /* CRC - inhibit tx CRC */ + bool crc_disable; /* CRC - inhibit tx CRC */ uint8_t loop_cntl; /* LB0,LB1 - loopback control */ - int ext_stoptx; /* ATD - allow tx disable by external mcast */ - int coll_prio; /* OFST - backoff algorithm select */ + bool ext_stoptx; /* ATD - allow tx disable by external mcast */ + bool coll_prio; /* OFST - backoff algorithm select */ uint8_t reserved; /* D5,D6,D7 - reserved */ } TCR; /* Transmit Status Register - 04h read */ struct TSR_t { - int tx_ok; /* PTX - tx complete without error */ - int reserved; /* D1 - reserved */ - int collided; /* COL - tx collided >= 1 times */ - int aborted; /* ABT - aborted due to excessive collisions */ - int no_carrier; /* CRS - carrier-sense lost */ - int fifo_ur; /* FU - FIFO underrun */ - int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ - int ow_coll; /* OWC - out-of-window collision */ + bool tx_ok; /* PTX - tx complete without error */ + bool reserved; /* D1 - reserved */ + bool collided; /* COL - tx collided >= 1 times */ + bool aborted; /* ABT - aborted due to excessive collisions */ + bool no_carrier; /* CRS - carrier-sense lost */ + bool fifo_ur; /* FU - FIFO underrun */ + bool cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ + bool ow_coll; /* OWC - out-of-window collision */ } TSR; /* Receive Configuration Register - 0ch write */ struct RCR_t { - int errors_ok; /* SEP - accept pkts with rx errors */ - int runts_ok; /* AR - accept < 64-byte runts */ - int broadcast; /* AB - accept eth broadcast address */ - int multicast; /* AM - check mcast hash array */ - int promisc; /* PRO - accept all packets */ - int monitor; /* MON - check pkts, but don't rx */ + bool errors_ok; /* SEP - accept pkts with rx errors */ + bool runts_ok; /* AR - accept < 64-byte runts */ + bool broadcast; /* AB - accept eth broadcast address */ + bool multicast; /* AM - check mcast hash array */ + bool promisc; /* PRO - accept all packets */ + bool monitor; /* MON - check pkts, but don't rx */ uint8_t reserved; /* D6,D7 - reserved */ } RCR; /* Receive Status Register - 0ch read */ struct RSR_t { - int rx_ok; /* PRX - rx complete without error */ - int bad_crc; /* CRC - Bad CRC detected */ - int bad_falign; /* FAE - frame alignment error */ - int fifo_or; /* FO - FIFO overrun */ - int rx_missed; /* MPA - missed packet error */ - int rx_mbit; /* PHY - unicast or mcast/bcast address match */ - int rx_disabled; /* DIS - set when in monitor mode */ - int deferred; /* DFR - collision active */ + bool rx_ok; /* PRX - rx complete without error */ + bool bad_crc; /* CRC - Bad CRC detected */ + bool bad_falign; /* FAE - frame alignment error */ + bool fifo_or; /* FO - FIFO overrun */ + bool rx_missed; /* MPA - missed packet error */ + bool rx_mbit; /* PHY - unicast or mcast/bcast address match */ + bool rx_disabled; /* DIS - set when in monitor mode */ + bool deferred; /* DFR - collision active */ } RSR; uint16_t local_dma; /* 01,02h read ; current local DMA addr */ diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index b35e0d453..0eba8a382 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index 623dec56c..a0e0e7129 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -198,6 +199,11 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) if (dev->TCR.loop_cntl) { dp8390_rx_common(dev, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes); + + if (dev->IMR.rx_inte && !dev->ISR.pkt_tx && dev->interrupt) + dev->interrupt(dev->priv, 1); + + dev->ISR.pkt_tx = 1; } } else if (val & 0x04) { if (dev->CR.stop || (!dev->CR.start && (dev->flags & DP8390_FLAG_CHECK_CR))) { @@ -220,12 +226,6 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) if (!(dev->card->link_state & NET_LINK_DOWN)) network_tx(dev->card, &dev->mem[((dev->tx_page_start * 256) - dev->mem_start) & dev->mem_wrap], dev->tx_bytes); - /* some more debug */ -#ifdef ENABLE_DP8390_LOG - if (dev->tx_timer_active) - dp8390_log("DP8390: CR write, tx timer still active\n"); -#endif - dp8390_tx(dev, val); } @@ -247,12 +247,12 @@ dp8390_tx(dp8390_t *dev, UNUSED(uint32_t val)) { dev->CR.tx_packet = 0; dev->TSR.tx_ok = 1; - dev->ISR.pkt_tx = 1; /* Generate an interrupt if not masked */ - if (dev->IMR.tx_inte && dev->interrupt) + if (dev->IMR.tx_inte && !dev->ISR.pkt_tx && dev->interrupt) dev->interrupt(dev->priv, 1); - dev->tx_timer_active = 0; + + dev->ISR.pkt_tx = 1; } /* @@ -960,7 +960,6 @@ dp8390_reset(dp8390_t *dev) memset(&dev->TCR, 0x00, sizeof(dev->TCR)); memset(&dev->TSR, 0x00, sizeof(dev->TSR)); memset(&dev->RSR, 0x00, sizeof(dev->RSR)); - dev->tx_timer_active = 0; dev->local_dma = 0; dev->page_start = 0; dev->page_stop = 0; diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index e45b55b22..4b9ef4a19 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -933,7 +934,7 @@ nic_init(const device_t *info) if (dev->board != NE2K_ETHERNEXT_MC) { dev->base_address = device_get_config_hex16("base"); dev->base_irq = device_get_config_int("irq"); - if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) || + if ((dev->board == NE2K_NE2000) || (dev->board == NE2K_NE2000_COMPAT) || (dev->board == NE2K_NE2000_COMPAT_8BIT) ) { dev->bios_addr = device_get_config_hex20("bios_addr"); dev->has_bios = !!dev->bios_addr; @@ -1061,7 +1062,7 @@ nic_init(const device_t *info) break; } - + if (set_oui) { /* See if we have a local MAC address configured. */ mac_oui = device_get_config_mac("mac_oui", -1); @@ -1742,7 +1743,7 @@ const device_t ne2000_compat_device = { const device_t ne2000_compat_8bit_device = { .name = "NE2000 Compatible 8-bit", .internal_name = "ne2k8", - .flags = DEVICE_ISA, + .flags = DEVICE_ISA, .local = NE2K_NE2000_COMPAT_8BIT, .init = nic_init, .close = nic_close, diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index 1ca8d8697..890b221e2 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include From dbbc49dc17dab9d422675aa63096b595d95aabeb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 10 Jul 2025 01:47:19 +0200 Subject: [PATCH 42/54] Add sanity checks to the Gameport pointer (July 10th, 2025) Fixes hangs/crashes when disabled on win3.1x and other software. --- src/sound/snd_sb.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index e612250b7..cb2ede45a 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1152,11 +1152,13 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) else if ((val & 0x06) == 0x02) mpu401_change_addr(sb->mpu, 0); } - sb->gameport_addr = 0; - gameport_remap(sb->gameport, 0); - if (!(val & 0x01)) { - sb->gameport_addr = 0x200; - gameport_remap(sb->gameport, 0x200); + if (sb->gameport != NULL) { + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); + if (!(val & 0x01)) { + sb->gameport_addr = 0x200; + gameport_remap(sb->gameport, 0x200); + } } } break; @@ -1371,7 +1373,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) else ret = 0x06; /* Should never happen. */ } - if (!sb->gameport_addr) + if (!sb->gameport_addr && (sb->gameport != NULL)) ret |= 0x01; break; @@ -1619,7 +1621,8 @@ ess_mixer_write(uint16_t addr, uint8_t val, void *priv) ess_fm_midi_write, NULL, NULL, ess); - gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); + if (ess->gameport != NULL) + gameport_remap(ess->gameport, !(mixer->regs[0x40] & 0x2) ? 0x00 : 0x200); if (ess->dsp.sb_subtype > SB_SUBTYPE_ESS_ES1688) { /* Not on ES1688. */ From ef17a9f3f2956eac1d1f7304c7b79858b532326c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 10 Jul 2025 01:57:23 +0200 Subject: [PATCH 43/54] Cleanup the fix. --- src/game/gameport.c | 3 +++ src/sound/snd_sb.c | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/game/gameport.c b/src/game/gameport.c index 67447d447..5bbfe8aac 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -306,6 +306,9 @@ gameport_remap(void *priv, uint16_t address) gameport_t *dev = (gameport_t *) priv; gameport_t *other_dev; + if (dev == NULL) + return; + if (dev->addr) { /* Remove this port from the active ports list. */ if (active_gameports == dev) { diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index cb2ede45a..4c73abf21 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1152,8 +1152,9 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) else if ((val & 0x06) == 0x02) mpu401_change_addr(sb->mpu, 0); } + + sb->gameport_addr = 0; if (sb->gameport != NULL) { - sb->gameport_addr = 0; gameport_remap(sb->gameport, 0); if (!(val & 0x01)) { sb->gameport_addr = 0x200; @@ -1373,7 +1374,7 @@ sb_ct1745_mixer_read(uint16_t addr, void *priv) else ret = 0x06; /* Should never happen. */ } - if (!sb->gameport_addr && (sb->gameport != NULL)) + if (!sb->gameport_addr) ret |= 0x01; break; From d79dd904eabd1614076af5f433e3e8e156c31f12 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 9 Jul 2025 19:45:26 -0400 Subject: [PATCH 44/54] Some corrections in snd_ssi2001.c --- src/sound/snd_ssi2001.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_ssi2001.c b/src/sound/snd_ssi2001.c index 9cc41c504..b832cb526 100644 --- a/src/sound/snd_ssi2001.c +++ b/src/sound/snd_ssi2001.c @@ -157,14 +157,13 @@ static const device_config_t ssi2001_config[] = { .description = "Enable Game port", .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 1, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, .bios = { { 0 } } }, - - { + { .name = "sid_config", .description = "SID Model", .type = CONFIG_HEX16, @@ -201,7 +200,7 @@ static const device_config_t entertainer_config[] = { .description = "Enable Game port", .type = CONFIG_BINARY, .default_string = NULL, - .default_int = 1, + .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, From c5d083bd28b4f6d9cf219072210cd0a6d51c5424 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 9 Jul 2025 19:45:44 -0400 Subject: [PATCH 45/54] read/writegus -> gus_read/write --- src/sound/snd_gus.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 5044c6f54..80ce6781d 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -246,7 +246,7 @@ gus_midi_update_int_status(gus_t *gus) } void -writegus(uint16_t addr, uint8_t val, void *priv) +gus_write(uint16_t addr, uint8_t val, void *priv) { gus_t *gus = (gus_t *) priv; int c; @@ -703,7 +703,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) } uint8_t -readgus(uint16_t addr, void *priv) +gus_read(uint16_t addr, void *priv) { gus_t *gus = (gus_t *) priv; uint8_t val = 0xff; @@ -1357,10 +1357,10 @@ gus_init(UNUSED(const device_t *info)) gus->base = device_get_config_hex16("base"); - io_sethandler(gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0100 + gus->base, 0x0010, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0506 + gus->base, 0x0001, readgus, NULL, NULL, writegus, NULL, NULL, gus); - io_sethandler(0x0388, 0x0002, readgus, NULL, NULL, writegus, NULL, NULL, gus); + io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0100 + gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); From 44fd79b78d36d971346728e0f3336b220975c1fb Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 10 Jul 2025 02:34:26 +0200 Subject: [PATCH 46/54] PCjr: Correctly implement wait states, fixes #3140. --- src/86box.c | 2 ++ src/game/gameport.c | 4 ++-- src/include/86box/86box.h | 3 ++- src/include/86box/mem.h | 2 ++ src/machine/m_pcjr.c | 2 ++ src/machine/machine.c | 2 ++ src/mem/mem.c | 6 ++++++ src/video/vid_pcjr.c | 16 ++++++++++++++++ 8 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/86box.c b/src/86box.c index 277d842b4..f8c3365ef 100644 --- a/src/86box.c +++ b/src/86box.c @@ -224,6 +224,8 @@ int other_ide_present = 0; /* IDE control int other_scsi_present = 0; /* SCSI controllers from non-SCSI cards are present */ +int is_pcjr = 0; /* The current machine is PCjr. */ + // Accelerator key array struct accelKey acc_keys[NUM_ACCELS]; diff --git a/src/game/gameport.c b/src/game/gameport.c index 5bbfe8aac..3025ee5eb 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -252,7 +252,7 @@ gameport_write(UNUSED(uint16_t addr), UNUSED(uint8_t val), void *priv) /* Notify the interface. */ joystick->intf->write(joystick->dat); - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES((8 << is_pcjr)); } static uint8_t @@ -268,7 +268,7 @@ gameport_read(UNUSED(uint16_t addr), void *priv) /* Merge axis state with button state. */ uint8_t ret = joystick->state | joystick->intf->read(joystick->dat); - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES((8 << is_pcjr)); return ret; } diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index bba99b555..55ba98567 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -154,9 +154,10 @@ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ extern int enable_discord; /* (C) enable Discord integration */ -extern int force_10ms; /* (C) force 10ms CPU frame interval */ +extern int force_10ms; /* (C) force 10ms CPU frame interval */ extern int other_ide_present; /* IDE controllers from non-IDE cards are present */ extern int other_scsi_present; /* SCSI controllers from non-SCSI cards are present */ +extern int is_pcjr; /* The current machine is PCjr. */ extern int hard_reset_pending; extern int fixed_size_x; diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 53001b8db..8710fca51 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -483,6 +483,8 @@ extern void mem_remap_top_nomid(int kb); extern void umc_smram_recalc(uint32_t start, int set); +extern void pcjr_waitstates(void *); + extern mem_mapping_t *read_mapping[MEM_MAPPINGS_NO]; extern mem_mapping_t *write_mapping[MEM_MAPPINGS_NO]; diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 30a5e609a..092c00b8f 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -829,6 +829,8 @@ machine_pcjr_init(UNUSED(const machine_t *model)) pcjr = calloc(1, sizeof(pcjr_t)); + is_pcjr = 1; + pic_init_pcjr(); pit_common_init(0, pit_irq0_timer_pcjr, NULL); diff --git a/src/machine/machine.c b/src/machine/machine.c index 6a86b785f..66bffdbd2 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -123,6 +123,8 @@ machine_init_ex(int m) pci_flags = 0x00000000; } + is_pcjr = 0; + /* All good, boot the machine! */ if (machines[m].init) ret = machines[m].init(&machines[m]); diff --git a/src/mem/mem.c b/src/mem/mem.c index fa749002c..a544f333c 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -1840,6 +1840,9 @@ mem_read_ram(uint32_t addr, UNUSED(void *priv)) mem_log("Read B %02X from %08X\n", ram[addr], addr); #endif + if (is_pcjr) + pcjr_waitstates(NULL); + if (cpu_use_exec) addreadlookup(mem_logical_addr, addr); @@ -2100,6 +2103,9 @@ mem_write_ram(uint32_t addr, uint8_t val, UNUSED(void *priv)) if ((addr >= 0xa0000) && (addr <= 0xbffff)) mem_log("Write B %02X to %08X\n", val, addr); #endif + if (is_pcjr) + pcjr_waitstates(NULL); + if (cpu_use_exec) { addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index 2b3eb730a..b4a2d24db 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -35,6 +35,8 @@ #include <86box/video.h> #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> +#include <86box/plat_unused.h> +#include "cpu.h" #include <86box/m_pcjr.h> @@ -194,6 +196,16 @@ vid_in(uint16_t addr, void *priv) return ret; } +void +pcjr_waitstates(UNUSED(void *priv)) +{ + int ws_array[16] = { 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5 }; + int ws; + + ws = ws_array[cycles & 0xf]; + cycles -= ws; +} + static void vid_write(uint32_t addr, uint8_t val, void *priv) { @@ -202,6 +214,8 @@ vid_write(uint32_t addr, uint8_t val, void *priv) if (pcjr->memctrl == -1) return; + pcjr_waitstates(NULL); + pcjr->b8000[addr & 0x3fff] = val; } @@ -213,6 +227,8 @@ vid_read(uint32_t addr, void *priv) if (pcjr->memctrl == -1) return 0xff; + pcjr_waitstates(NULL); + return (pcjr->b8000[addr & 0x3fff]); } From 0ca13a7cac74b7bd3f327b869006415855acb173 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 10 Jul 2025 04:36:28 +0200 Subject: [PATCH 47/54] Make sure graphics cards are in alphabetical order and fix the name of the C&T SuperEGA. --- src/video/vid_ega.c | 2 +- src/video/vid_table.c | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 21671f4b3..26bb38991 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -1895,7 +1895,7 @@ const device_t cpqega_device = { }; const device_t sega_device = { - .name = "SuperEGA", + .name = "Chips & Technologies SuperEGA", .internal_name = "superega", .flags = DEVICE_ISA, .local = EGA_SUPEREGA, diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 2e42e5c2c..1196db294 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -53,37 +53,39 @@ video_cards[] = { { .device = &device_none, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &device_internal, .flags = VIDEO_FLAG_TYPE_NONE }, /* ISA */ + { .device = &ati18800_wonder_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ati18800_vga88_device, .flags = VIDEO_FLAG_TYPE_NONE }, +#ifdef USE_XL24 + { .device = &ati28800_wonderxl24_device, .flags = VIDEO_FLAG_TYPE_NONE }, +#endif /* USE_XL24 */ + { .device = &ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &compaq_ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ati28800_wonder1024d_xl_plus_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &atiega800p_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &mach8_vga_isa_device, .flags = VIDEO_FLAG_TYPE_8514 }, { .device = &mach32_isa_device, .flags = VIDEO_FLAG_TYPE_8514 }, { .device = &ati28800k_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati18800_vga88_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &compaq_ati28800_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati28800_wonder1024d_xl_plus_device, .flags = VIDEO_FLAG_TYPE_NONE }, -#ifdef USE_XL24 - { .device = &ati28800_wonderxl24_device, .flags = VIDEO_FLAG_TYPE_NONE }, -#endif /* USE_XL24 */ { .device = &ati18800_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ati18800_wonder_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &quadcolor_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &sega_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &jega_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5401_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5402_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &colorplus_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &compaq_cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &compaq_cga_2_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &cpqega_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &g2_gc205_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &hercules_device, .flags = VIDEO_FLAG_TYPE_MDA }, { .device = &herculesplus_device, .flags = VIDEO_FLAG_TYPE_MDA }, { .device = &incolor_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &cga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &mda_device, .flags = VIDEO_FLAG_TYPE_MDA }, + { .device = &pgc_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &vga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &im1024_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &iskra_ega_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &jega_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000_kasan_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &mda_device, .flags = VIDEO_FLAG_TYPE_MDA }, { .device = &genius_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -94,9 +96,8 @@ video_cards[] = { { .device = ¶dise_pvga1a_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = ¶dise_wd90c11_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = ¶dise_wd90c30_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &colorplus_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &pgc_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &cga_pravetz_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &quadcolor_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &realtek_rtg3105_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &realtek_rtg3106_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &sigma_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -110,7 +111,6 @@ video_cards[] = { { .device = &et3000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000_tc6058af_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &vga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &v7_vga_1024i_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &wy700_device, .flags = VIDEO_FLAG_TYPE_NONE }, /* ISA16 */ From ea3ee8c9af2cd09d39732465e8d0a51722010e54 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 10 Jul 2025 04:38:07 +0200 Subject: [PATCH 48/54] Move the NEC Trident to its correct place. --- src/video/vid_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 1196db294..2834213c7 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -88,6 +88,7 @@ video_cards[] = { { .device = &et4000_kasan_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &genius_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -105,7 +106,6 @@ video_cards[] = { { .device = &tvga8900d_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &tvga8900dr_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &tvga9000b_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000k_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et2000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et3000_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, From d71942909e1215c2054aee82b2b4b935cb39fe0e Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 6 Aug 2024 13:53:26 -0400 Subject: [PATCH 49/54] Correct internal name for Tandy 1000 SX --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 87dd38786..94c03ebe6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1564,7 +1564,7 @@ const machine_t machines[] = { }, { .name = "[8088] Tandy 1000 SX", - .internal_name = "tandy", + .internal_name = "tandy1000sx", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_PROPRIETARY, .init = machine_tandy1000sx_init, From 7073a184fecd5b43d488ce0d7c7145d3ad94ede1 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 10 Jul 2025 10:30:44 -0300 Subject: [PATCH 50/54] Internal name migration for Tandy 1000 SX --- src/config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 76abbae23..72c5cc148 100644 --- a/src/config.c +++ b/src/config.c @@ -265,7 +265,9 @@ load_machine(void) if (p != NULL) { migrate_from = p; /* Migrate renamed machines. */ - if (!strcmp(p, "430nx")) + if (!strcmp(p, "tandy")) + machine = machine_get_machine_from_internal_name("tandy1000sx"); + else if (!strcmp(p, "430nx")) machine = machine_get_machine_from_internal_name("586ip"); else if (!strcmp(p, "586mc1")) machine = machine_get_machine_from_internal_name("586is"); From e7d0f153ae655db189ec8812861e1f873eb275da Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 10 Jul 2025 10:42:08 -0300 Subject: [PATCH 51/54] Move PS/2 floppy drive type migration to config --- src/config.c | 11 +++++++++-- src/floppy/fdd.c | 11 +---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/config.c b/src/config.c index 72c5cc148..bf9be4911 100644 --- a/src/config.c +++ b/src/config.c @@ -1215,14 +1215,20 @@ load_floppy_and_cdrom_drives(void) unsigned int board = 0; unsigned int dev = 0; int c; - int d = 0; + int d; int count = cdrom_get_type_count(); memset(temp, 0x00, sizeof(temp)); for (c = 0; c < FDD_NUM; c++) { sprintf(temp, "fdd_%02i_type", c + 1); p = ini_section_get_string(cat, temp, (c < 2) ? "525_2dd" : "none"); - fdd_set_type(c, fdd_get_from_internal_name(p)); + if (!strcmp(p, "525_2hd_ps2")) + d = fdd_get_from_internal_name("525_2hd"); + else if (!strcmp(p, "35_2hd_ps2")) + d = fdd_get_from_internal_name("35_2hd"); + else + d = fdd_get_from_internal_name(p); + fdd_set_type(c, d); if (fdd_get_type(c) > 13) fdd_set_type(c, 13); @@ -1301,6 +1307,7 @@ load_floppy_and_cdrom_drives(void) ini_section_delete_var(cat, temp); sprintf(temp, "cdrom_%02i_parameters", c + 1); + d = 0; p = ini_section_get_string(cat, temp, NULL); if (p != NULL) sscanf(p, "%01u, %s", &d, s); diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 31811069f..1623f932a 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -212,18 +212,9 @@ int fdd_get_from_internal_name(char *s) { int c = 0; - char *n; - - /* TODO: Remove this once the migration period is over. */ - if (!strcmp(s, "525_2hd_ps2")) - n = "525_2hd"; - else if (!strcmp(s, "35_2hd_ps2")) - n = "35_2hd"; - else - n = s; while (strlen(drive_types[c].internal_name)) { - if (!strcmp((char *) drive_types[c].internal_name, n)) + if (!strcmp((char *) drive_types[c].internal_name, s)) return c; c++; } From 030c25cf2d47a30f2fdad4767e16f77cdaca2dfb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 10 Jul 2025 12:06:59 -0300 Subject: [PATCH 52/54] ISA ROM system cleanups --- src/device/isarom.c | 71 ++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/device/isarom.c b/src/device/isarom.c index cdf5a61c6..0b7c38a54 100644 --- a/src/device/isarom.c +++ b/src/device/isarom.c @@ -26,9 +26,11 @@ #include <86box/nvr.h> #include <86box/isarom.h> -#define ISAROM_CARD 0 -#define ISAROM_CARD_DUAL 1 -#define ISAROM_CARD_QUAD 2 +enum { + ISAROM_CARD = 0, + ISAROM_CARD_DUAL, + ISAROM_CARD_QUAD +}; #ifdef ENABLE_ISAROM_LOG int isarom_do_log = ENABLE_ISAROM_LOG; @@ -56,7 +58,7 @@ typedef struct isarom_t { uint32_t size; uint32_t len; char nvr_path[64]; - uint8_t wp; + uint8_t writable; } socket[4]; uint8_t inst; uint8_t type; @@ -65,11 +67,14 @@ typedef struct isarom_t { static inline uint8_t get_limit(uint8_t type) { - if (type == ISAROM_CARD_DUAL) - return 2; - if (type == ISAROM_CARD_QUAD) - return 4; - return 1; + switch (type) { + case ISAROM_CARD_DUAL: + return 2; + case ISAROM_CARD_QUAD: + return 4; + default: + return 1; + } } static inline void @@ -92,12 +97,13 @@ isarom_close(void *priv) if (!priv) return; - for (uint8_t i = 0; i < get_limit(dev->type); i++) - if (dev->socket[i].rom.rom) { + for (uint8_t i = 0; i < get_limit(dev->type); i++) { + if (dev->socket[i].writable) { isarom_log("isarom[%u]: saving NVR for socket %u -> %s (%u bytes)\n", dev->inst, i, dev->socket[i].nvr_path, dev->socket[i].size); isarom_save_nvr(dev->socket[i].nvr_path, dev->socket[i].rom.rom, dev->socket[i].size); } + } free(dev); } @@ -115,32 +121,37 @@ isarom_init(const device_t *info) isarom_log("isarom[%u]: initializing device (type=%u)\n", dev->inst, dev->type); for (uint8_t i = 0; i < get_limit(dev->type); i++) { - char key_fn[12]; - char key_addr[14]; - char key_size[14]; - char key_writes[22]; + char s[22]; char suffix[4] = ""; if (i > 0) snprintf(suffix, sizeof(suffix), "%d", i + 1); - snprintf(key_fn, sizeof(key_fn), "bios_fn%s", suffix); - snprintf(key_addr, sizeof(key_addr), "bios_addr%s", suffix); - snprintf(key_size, sizeof(key_size), "bios_size%s", suffix); - snprintf(key_writes, sizeof(key_writes), "rom_writes_enabled%s", suffix); + snprintf(s, sizeof(s), "bios_addr%s", suffix); + dev->socket[i].addr = device_get_config_hex20(s); - dev->socket[i].fn = device_get_config_string(key_fn); - dev->socket[i].addr = device_get_config_hex20(key_addr); - dev->socket[i].size = device_get_config_int(key_size); - // Note: 2K is the smallest ROM I've found, but 86box's memory granularity is 4k, the number below is fine - // as we'll end up allocating no less than 4k due to the device config limits. - dev->socket[i].len = (dev->socket[i].size > 2048) ? dev->socket[i].size - 1 : 0; - dev->socket[i].wp = (uint8_t) device_get_config_int(key_writes) ? 1 : 0; + switch (dev->type) { + default: + snprintf(s, sizeof(s), "bios_fn%s", suffix); + dev->socket[i].fn = device_get_config_string(s); - isarom_log("isarom[%u]: socket %u: addr=0x%05X size=%u wp=%u fn=%s\n", + snprintf(s, sizeof(s), "bios_size%s", suffix); + dev->socket[i].size = device_get_config_int(s); + + snprintf(s, sizeof(s), "rom_writes_enabled%s", suffix); + if (device_get_config_int(s)) + dev->socket[i].writable = 1; + break; + } + + /* Note: 2K is the smallest ROM I've found, but 86Box's memory granularity is 4K, the number + below is fine as we'll end up allocating no less than 4K due to the device config limits. */ + dev->socket[i].len = (dev->socket[i].size > 0) ? ((dev->socket[i].size - 1) | MEM_GRANULARITY_MASK) : 0; + + isarom_log("isarom[%u]: socket %u: addr=0x%05X size=%u writable=%u fn=%s\n", dev->inst, i, dev->socket[i].addr, dev->socket[i].size, - dev->socket[i].wp, dev->socket[i].fn ? dev->socket[i].fn : "(null)"); + dev->socket[i].writable, dev->socket[i].fn ? dev->socket[i].fn : "(null)"); - if (dev->socket[i].addr != 0 && dev->socket[i].fn != NULL) { + if ((dev->socket[i].addr != 0) && (dev->socket[i].fn != NULL)) { rom_init(&dev->socket[i].rom, dev->socket[i].fn, dev->socket[i].addr, @@ -151,7 +162,7 @@ isarom_init(const device_t *info) isarom_log("isarom[%u]: ROM initialized for socket %u\n", dev->inst, i); - if (dev->socket[i].wp) { + if (dev->socket[i].writable) { mem_mapping_set_write_handler(&dev->socket[i].rom.mapping, rom_write, rom_writew, rom_writel); snprintf(dev->socket[i].nvr_path, sizeof(dev->socket[i].nvr_path), "isarom_%i_%i.nvr", dev->inst, i + 1); FILE *fp = nvr_fopen(dev->socket[i].nvr_path, "rb"); From 19bd891f86364a709455ae2f33156775f7331649 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 10 Jul 2025 12:10:16 -0300 Subject: [PATCH 53/54] Move LBA Enhancer to the ISA ROM system --- src/86box.c | 4 - src/config.c | 31 +++++-- src/device/isarom.c | 64 +++++++++++++-- src/disk/CMakeLists.txt | 1 - src/disk/lba_enhancer.c | 100 ----------------------- src/include/86box/86box.h | 1 - src/include/86box/hdc.h | 3 - src/qt/qt_settingsstoragecontrollers.cpp | 16 ---- src/qt/qt_settingsstoragecontrollers.hpp | 3 - src/qt/qt_settingsstoragecontrollers.ui | 37 --------- 10 files changed, 81 insertions(+), 179 deletions(-) delete mode 100644 src/disk/lba_enhancer.c diff --git a/src/86box.c b/src/86box.c index f8c3365ef..d773e35cb 100644 --- a/src/86box.c +++ b/src/86box.c @@ -188,7 +188,6 @@ int gfxcard[GFXCARD_MAX] = { 0, 0 }; /* (C) graphic int show_second_monitors = 1; /* (C) show non-primary monitors */ int sound_is_float = 1; /* (C) sound uses FP values */ int voodoo_enabled = 0; /* (C) video option */ -int lba_enhancer_enabled = 0; /* (C) enable Vision Systems LBA Enhancer */ int ibm8514_standalone_enabled = 0; /* (C) video option */ int xga_standalone_enabled = 0; /* (C) video option */ int da2_standalone_enabled = 0; /* (C) video option */ @@ -1535,9 +1534,6 @@ pc_reset_hard_init(void) if (unittester_enabled) device_add(&unittester_device); - if (lba_enhancer_enabled) - device_add(&lba_enhancer_device); - if (novell_keycard_enabled) device_add(&novell_keycard_device); diff --git a/src/config.c b/src/config.c index bf9be4911..acfbec758 100644 --- a/src/config.c +++ b/src/config.c @@ -994,11 +994,6 @@ load_storage_controllers(void) } } } - - lba_enhancer_enabled = !!ini_section_get_int(cat, "lba_enhancer_enabled", 0); - - if (!lba_enhancer_enabled) - ini_section_delete_var(cat, "lba_enhancer_enabled"); } /* Load "Hard Disks" section. */ @@ -1736,6 +1731,17 @@ load_other_peripherals(void) ini_section_delete_var(cat, temp); } + /* Backwards compatibility for standalone LBA Enhancer from v4.2 and older. */ + if (ini_section_get_int(ini_find_section(config, "Storage controllers"), "lba_enhancer_enabled", 0) == 1) { + /* Migrate to the first available ISA ROM slot. */ + for (uint8_t c = 0; c < ISAROM_MAX; c++) { + if (!isarom_type[c]) { + isarom_type[c] = isarom_get_from_internal_name("lba_enhancer"); + break; + } + } + } + p = ini_section_get_string(cat, "isartc_type", "none"); isartc_type = isartc_get_from_internal_name(p); @@ -2706,10 +2712,19 @@ save_storage_controllers(void) } } - if (lba_enhancer_enabled == 0) + /* Downgrade compatibility for standalone LBA Enhancer from v4.2 and older. */ + int card_id = isarom_get_from_internal_name("lba_enhancer"); + for (c = 0; c < ISAROM_MAX; c++) { + if (isarom_type[c] == card_id) { + /* A special value of 2 still enables the cards on older versions, + but lets newer versions know that they've already been migrated. */ + ini_section_set_int(cat, "lba_enhancer_enabled", 2); + card_id = 0; /* mark as found */ + break; + } + } + if (card_id > 0) /* not found */ ini_section_delete_var(cat, "lba_enhancer_enabled"); - else - ini_section_set_int(cat, "lba_enhancer_enabled", 1); ini_delete_section_if_empty(config, cat); } diff --git a/src/device/isarom.c b/src/device/isarom.c index 0b7c38a54..d5158f4cd 100644 --- a/src/device/isarom.c +++ b/src/device/isarom.c @@ -29,9 +29,12 @@ enum { ISAROM_CARD = 0, ISAROM_CARD_DUAL, - ISAROM_CARD_QUAD + ISAROM_CARD_QUAD, + ISAROM_CARD_LBA_ENHANCER }; +#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" + #ifdef ENABLE_ISAROM_LOG int isarom_do_log = ENABLE_ISAROM_LOG; @@ -130,6 +133,11 @@ isarom_init(const device_t *info) dev->socket[i].addr = device_get_config_hex20(s); switch (dev->type) { + case ISAROM_CARD_LBA_ENHANCER: + dev->socket[i].fn = BIOS_LBA_ENHANCER; + dev->socket[i].size = 0x4000; + break; + default: snprintf(s, sizeof(s), "bios_fn%s", suffix); dev->socket[i].fn = device_get_config_string(s); @@ -179,6 +187,12 @@ isarom_init(const device_t *info) return dev; } +static int +isarom_lba_enhancer_available(void) +{ + return rom_present(BIOS_LBA_ENHANCER); +} + #define BIOS_FILE_FILTER "ROM files (*.bin *.rom)|*.bin,*.rom" #define BIOS_ADDR_SELECTION { \ @@ -539,6 +553,29 @@ static const device_config_t isarom_quad_config[] = { }, { .name = "", .description = "", .type = CONFIG_END } }; + +static const device_config_t lba_enhancer_config[] = { + { + .name = "bios_addr", + .description = "BIOS Address", + .type = CONFIG_HEX20, + .default_string = NULL, + .default_int = 0xc8000, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "C800H", .value = 0xc8000 }, + { .description = "CC00H", .value = 0xcc000 }, + { .description = "D000H", .value = 0xd0000 }, + { .description = "D400H", .value = 0xd4000 }, + { .description = "D800H", .value = 0xd8000 }, + { .description = "DC00H", .value = 0xdc000 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; // clang-format on static const device_t isarom_device = { @@ -583,15 +620,30 @@ static const device_t isarom_quad_device = { .config = isarom_quad_config }; +static const device_t lba_enhancer_device = { + .name = "Vision Systems LBA Enhancer", + .internal_name = "lba_enhancer", + .flags = DEVICE_ISA, + .local = ISAROM_CARD_LBA_ENHANCER, + .init = isarom_init, + .close = isarom_close, + .reset = NULL, + .available = isarom_lba_enhancer_available, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lba_enhancer_config +}; + static const struct { const device_t *dev; } boards[] = { // clang-format off - { &device_none }, - { &isarom_device }, - { &isarom_dual_device }, - { &isarom_quad_device }, - { NULL } + { &device_none }, + { &isarom_device }, + { &isarom_dual_device }, + { &isarom_quad_device }, + { &lba_enhancer_device }, + { NULL } // clang-format on }; diff --git a/src/disk/CMakeLists.txt b/src/disk/CMakeLists.txt index bdbb9e74c..48d9e61ff 100644 --- a/src/disk/CMakeLists.txt +++ b/src/disk/CMakeLists.txt @@ -35,7 +35,6 @@ add_library(hdd OBJECT hdc_ide_sff8038i.c hdc_ide_um8673f.c hdc_ide_w83769f.c - lba_enhancer.c ) add_library(zip OBJECT zip.c) diff --git a/src/disk/lba_enhancer.c b/src/disk/lba_enhancer.c deleted file mode 100644 index ef9e167d3..000000000 --- a/src/disk/lba_enhancer.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Vision Systems LBA Enhancer emulation. - * - * - * - * Authors: Cacodemon345 - * - * Copyright 2024 Cacodemon345 - */ - -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/device.h> -#include <86box/mem.h> -#include <86box/rom.h> -#include <86box/plat_unused.h> - -typedef struct lba_enhancer_t -{ - rom_t rom; -} lba_enhancer_t; - -#define BIOS_LBA_ENHANCER "roms/hdd/misc/lbaenhancer.bin" - -void -lba_enhancer_close(void* priv) -{ - free(priv); - - return; -} - -void * -lba_enhancer_init(UNUSED(const device_t *info)) -{ - lba_enhancer_t *dev = (lba_enhancer_t *) calloc(1, sizeof(lba_enhancer_t)); - - rom_init(&dev->rom, BIOS_LBA_ENHANCER, - device_get_config_hex20("bios_addr"), 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - - return dev; -} - -static int -lba_enhancer_available(void) -{ - return rom_present(BIOS_LBA_ENHANCER); -} - -// clang-format off -static const device_config_t lba_enhancer_config[] = { - { - .name = "bios_addr", - .description = "BIOS Address", - .type = CONFIG_HEX20, - .default_string = NULL, - .default_int = 0xc8000, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { - { .description = "C800H", .value = 0xc8000 }, - { .description = "CC00H", .value = 0xcc000 }, - { .description = "D000H", .value = 0xd0000 }, - { .description = "D400H", .value = 0xd4000 }, - { .description = "D800H", .value = 0xd8000 }, - { .description = "DC00H", .value = 0xdc000 }, - { .description = "" } - }, - .bios = { { 0 } } - }, - { .name = "", .description = "", .type = CONFIG_END } -}; -// clang-format on - -const device_t lba_enhancer_device = { - .name = "Vision Systems LBA Enhancer", - .internal_name = "lba_enhancer", - .flags = DEVICE_ISA16, - .local = 0, - .init = lba_enhancer_init, - .close = lba_enhancer_close, - .reset = NULL, - .available = lba_enhancer_available, - .speed_changed = NULL, - .force_redraw = NULL, - .config = lba_enhancer_config -}; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 55ba98567..4494290d6 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -149,7 +149,6 @@ extern int fpu_type; /* (C) fpu type */ extern int fpu_softfloat; /* (C) fpu uses softfloat */ extern int time_sync; /* (C) enable time sync */ extern int hdd_format_type; /* (C) hard disk file format */ -extern int lba_enhancer_enabled; /* (C) enable Vision Systems LBA Enhancer */ extern int confirm_reset; /* (C) enable reset confirmation */ extern int confirm_exit; /* (C) enable exit confirmation */ extern int confirm_save; /* (C) enable save confirmation */ diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 0a5985370..ca020b4b2 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -112,9 +112,6 @@ extern const device_t xtide_acculogic_device; /* xtide_ps2 */ extern const device_t xtide_at_ps2_device; /* xtide_at_ps2 */ extern const device_t xtide_at_ps2_2ch_device; /* xtide_at_ps2_2ch */ -/* Miscellaneous */ -extern const device_t lba_enhancer_device; - extern void hdc_init(void); extern void hdc_reset(void); diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index d282bcb8b..5c9b24c46 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -62,7 +62,6 @@ SettingsStorageControllers::save() ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; - lba_enhancer_enabled = ui->checkBoxLbaEnhancer->isChecked() ? 1 : 0; } void @@ -232,9 +231,6 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->checkBoxCassette->setChecked(false); ui->checkBoxCassette->setEnabled(false); } - - ui->checkBoxLbaEnhancer->setChecked(lba_enhancer_enabled > 0 && device_available(&lba_enhancer_device)); - ui->pushButtonConfigureLbaEnhancer->setEnabled(ui->checkBoxLbaEnhancer->isChecked()); } void @@ -365,15 +361,3 @@ SettingsStorageControllers::on_pushButtonSCSI4_clicked() { DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4); } - -void -SettingsStorageControllers::on_checkBoxLbaEnhancer_stateChanged(int arg1) -{ - ui->pushButtonConfigureLbaEnhancer->setEnabled(arg1 != 0); -} - -void -SettingsStorageControllers::on_pushButtonConfigureLbaEnhancer_clicked() -{ - DeviceConfig::ConfigureDevice(&lba_enhancer_device); -} diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp index 7c1c56086..074b48dbd 100644 --- a/src/qt/qt_settingsstoragecontrollers.hpp +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -44,9 +44,6 @@ private slots: void on_comboBoxSCSI4_currentIndexChanged(int index); void on_pushButtonSCSI4_clicked(); - void on_checkBoxLbaEnhancer_stateChanged(int arg1); - void on_pushButtonConfigureLbaEnhancer_clicked(); - private: Ui::SettingsStorageControllers *ui; int machineId = 0; diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index cd1bf9baf..b9eb310ba 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -257,43 +257,6 @@ - - - - 0 - - - 0 - - - - - Vision Systems LBA Enhancer - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Configure - - - - - From f974fad3afb4bc7bdf9df60d49eb1d672e758e1d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 10 Jul 2025 12:24:46 -0300 Subject: [PATCH 54/54] ISA ROM: Clarify a variable name [skip ci] --- src/device/isarom.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/device/isarom.c b/src/device/isarom.c index d5158f4cd..e7964d445 100644 --- a/src/device/isarom.c +++ b/src/device/isarom.c @@ -124,13 +124,13 @@ isarom_init(const device_t *info) isarom_log("isarom[%u]: initializing device (type=%u)\n", dev->inst, dev->type); for (uint8_t i = 0; i < get_limit(dev->type); i++) { - char s[22]; + char str[22]; char suffix[4] = ""; if (i > 0) snprintf(suffix, sizeof(suffix), "%d", i + 1); - snprintf(s, sizeof(s), "bios_addr%s", suffix); - dev->socket[i].addr = device_get_config_hex20(s); + snprintf(str, sizeof(str), "bios_addr%s", suffix); + dev->socket[i].addr = device_get_config_hex20(str); switch (dev->type) { case ISAROM_CARD_LBA_ENHANCER: @@ -139,14 +139,14 @@ isarom_init(const device_t *info) break; default: - snprintf(s, sizeof(s), "bios_fn%s", suffix); - dev->socket[i].fn = device_get_config_string(s); + snprintf(str, sizeof(str), "bios_fn%s", suffix); + dev->socket[i].fn = device_get_config_string(str); - snprintf(s, sizeof(s), "bios_size%s", suffix); - dev->socket[i].size = device_get_config_int(s); + snprintf(str, sizeof(str), "bios_size%s", suffix); + dev->socket[i].size = device_get_config_int(str); - snprintf(s, sizeof(s), "rom_writes_enabled%s", suffix); - if (device_get_config_int(s)) + snprintf(str, sizeof(str), "rom_writes_enabled%s", suffix); + if (device_get_config_int(str)) dev->socket[i].writable = 1; break; }