From 2141353592d91a122ec336771be0bd3d14523b29 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Sep 2025 00:44:16 +0200 Subject: [PATCH 01/30] Minor cleanup on 53c9x code (September 7th, 2025) --- src/scsi/scsi_pcscsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 04c188705..2c73066a1 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1274,7 +1274,7 @@ esp_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - if ((dev->rregs[ESP_CFG3] & 0x18) == 0x18) { + if ((dev->wregs[ESP_CFG3] & 0x18) == 0x18) { /* Fast SCSI: 10000000 bytes per second */ dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); } else { @@ -1537,11 +1537,11 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_pci_soft_reset(dev); break; case CMD_BUSRESET: - esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); + esp_log("ESP Bus Reset val=%02x.\n", (dev->wregs[ESP_CFG1] & CFG1_RESREPT)); for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { + if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); @@ -1579,7 +1579,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_raise_irq(dev); break; case CMD_PAD: - esp_log("val = %02X\n", val); + esp_log("PAD=%02X\n", val); timer_stop(&dev->timer); timer_on_auto(&dev->timer, dev->period); esp_log("ESP Transfer Pad\n"); @@ -2214,7 +2214,8 @@ esp_pci_reset(void *priv) esp_pci_soft_reset(dev); esp_log("PCI Reset.\n"); - } + } else + esp_log("NULL.\n"); } static void * From a6becc31580b370d0b06cc002731a42c7a245d37 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Sep 2025 01:01:03 +0200 Subject: [PATCH 02/30] Major video changes and fixes of the day (September 7th, 2025) 1. Rewritten Sierra SC1502x RAMDAC code to match the manual, allowing proper BPP selection on cards which use it. 2. Added a reference clock variable for cards which have a different default one (ELSA cards namely) on the ICD2061 code. 3. Reorganized RAMDAC selection in the S3 code. 4. Added more ELSA Winner cards based on the 928 chip (ELSA Winner 2000 ISA, 1000 VLB and 1000 PCI based on 928PCI). 5. The horizontal override is now also enabled for ELSA Winner 1000 (928 VLB and PCI) cards with 32bpp set, to avoid wrong horizontal displays. 6. LFB in PCI mode doesn't have the same limitations as on VLB or ISA. 7. Added more hdisp adjustments for the Elsa cards. 8. Mono patterns are now more correct in ROPBLT acceleration (command 14), fixes blackness in some instances of Win95 (matching the 968 manual). 9. Minor cleanup on the accel registers. --- src/include/86box/vid_svga.h | 4 + src/include/86box/video.h | 11 +- src/video/clockgen/vid_clockgen_icd2061.c | 21 +- src/video/ramdac/vid_ramdac_sc1502x.c | 261 ++++++--- src/video/vid_s3.c | 647 ++++++++++++++++++---- src/video/vid_table.c | 5 +- 6 files changed, 757 insertions(+), 192 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index b588a3daf..a66dd8c03 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -449,6 +449,7 @@ extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float r extern void icd2061_write(void *priv, int val); extern float icd2061_getclock(int clock, void *priv); +extern void icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock); /* The code is the same, the #define's are so that the correct name can be used. */ # define ics9161_write icd2061_write @@ -465,6 +466,8 @@ extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svg extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern void sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); @@ -516,6 +519,7 @@ extern const device_t sc11487_ramdac_device; extern const device_t sc11486_ramdac_device; extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; +extern const device_t sc1502x_rs2_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; extern const device_t tkd8001_ramdac_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b5be81bbb..81424dbcb 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -412,7 +412,7 @@ extern const device_t cga_pravetz_device; /* Compaq CGA */ extern const device_t compaq_cga_device; extern const device_t compaq_cga_2_device; -extern const device_t compaq_plasma_device; +extern const device_t compaq_plasma_device; /* Olivetti OGC */ extern const device_t ogc_device; @@ -513,8 +513,11 @@ extern const device_t realtek_rtg3106_device; extern const device_t s3_orchid_86c911_isa_device; extern const device_t s3_diamond_stealth_vram_isa_device; extern const device_t s3_ami_86c924_isa_device; +extern const device_t s3_elsa_winner1000_86c928_vlb_device; +extern const device_t s3_elsa_winner2000_86c928_isa_device; extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_device; +extern const device_t s3_elsa_winner1000_86c928_pci_device; extern const device_t s3_spea_mercury_lite_86c928_pci_device; extern const device_t s3_spea_mirage_86c801_isa_device; extern const device_t s3_winner1000_805_isa_device; @@ -635,9 +638,9 @@ extern const device_t wy700_device; extern const device_t v6355d_device; /* Tandy */ -extern const device_t tandy_1000_video_device; -extern const device_t tandy_1000hx_video_device; -extern const device_t tandy_1000sl_video_device; +extern const device_t tandy_1000_video_device; +extern const device_t tandy_1000hx_video_device; +extern const device_t tandy_1000sl_video_device; #endif diff --git a/src/video/clockgen/vid_clockgen_icd2061.c b/src/video/clockgen/vid_clockgen_icd2061.c index 7b80a5484..f1925e769 100644 --- a/src/video/clockgen/vid_clockgen_icd2061.c +++ b/src/video/clockgen/vid_clockgen_icd2061.c @@ -29,10 +29,15 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> #include <86box/plat_unused.h> typedef struct icd2061_t { - float freq[3]; + float freq[3]; + float ref_clock; int count; int bit_count; @@ -121,7 +126,7 @@ icd2061_write(void *priv, int val) q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * 14318184.0f; + icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * icd2061->ref_clock; icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); } else if (a == 6) { @@ -149,12 +154,24 @@ icd2061_getclock(int clock, void *priv) return icd2061->freq[clock]; } +void +icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock) +{ + icd2061_t *icd2061 = (icd2061_t *) priv; + + if (icd2061) + icd2061->ref_clock = ref_clock; + + svga_recalctimings(svga); +} + static void * icd2061_init(UNUSED(const device_t *info)) { icd2061_t *icd2061 = (icd2061_t *) malloc(sizeof(icd2061_t)); memset(icd2061, 0, sizeof(icd2061_t)); + icd2061->ref_clock = 14318184.0f; icd2061->freq[0] = 25175000.0; icd2061->freq[1] = 28322000.0; icd2061->freq[2] = 28322000.0; diff --git a/src/video/ramdac/vid_ramdac_sc1502x.c b/src/video/ramdac/vid_ramdac_sc1502x.c index 1c7d4014d..4fc603ee9 100644 --- a/src/video/ramdac/vid_ramdac_sc1502x.c +++ b/src/video/ramdac/vid_ramdac_sc1502x.c @@ -33,65 +33,32 @@ typedef struct sc1502x_ramdac_t { int state; + int use_rs2; uint8_t ctrl; uint8_t idx; uint8_t regs[256]; uint32_t pixel_mask; - uint8_t enable_ext; } sc1502x_ramdac_t; static void -sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga) { - int oldbpp = 0; - if (val == 0xff) - return; - ramdac->ctrl = val; - oldbpp = svga->bpp; - switch ((val & 1) | ((val & 0xc0) >> 5)) { - case 0: - svga->bpp = 8; - break; - case 2: - case 3: - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: + int oldbpp = svga->bpp; + if (ramdac->ctrl & 0x80) { + if (ramdac->ctrl & 0x40) { svga->bpp = 16; - break; - case 7: - if (val & 4) { - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - } else - svga->bpp = 16; - break; - - default: - break; + } else + svga->bpp = 15; + } else { + if (ramdac->ctrl & 0x40) { + if (ramdac->regs[0x10] & 0x01) + svga->bpp = 32; + else if (ramdac->ctrl & 0x20) + svga->bpp = 24; + else + svga->bpp = 32; + } else + svga->bpp = 8; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -104,29 +71,30 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) switch (addr) { case 0x3C6: - if (ramdac->state == 0) - ramdac->enable_ext = (val == 0x10); - - if (ramdac->state == 4) { + if ((ramdac->state == 4) || (ramdac->ctrl & 0x10)) { ramdac->state = 0; - sc1502x_ramdac_bpp(val, ramdac, svga); + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); return; } ramdac->state = 0; + svga_out(addr, val, svga); break; case 0x3C7: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) ramdac->idx = val; - return; - } + else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 8: - ramdac->regs[ramdac->idx] = val; - svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? RAMDAC_8BIT : RAMDAC_6BIT); + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; break; case 0x0d: ramdac->pixel_mask = val & svga->dac_mask; @@ -137,24 +105,96 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) case 0x0f: ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; default: ramdac->regs[ramdac->idx] = val; break; } - return; - } + } else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) - return; ramdac->state = 0; + svga_out(addr, val, svga); break; default: break; } - svga_out(addr, val, svga); +} + +void +sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 8: + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x0d: + ramdac->pixel_mask = val & svga->dac_mask; + break; + case 0x0e: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 8); + break; + case 0x0f: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); + break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; + default: + ramdac->regs[ramdac->idx] = val; + break; + } + } else + svga_out(addr, val, svga); + break; + case 0x01: + svga_out(addr, val, svga); + break; + case 0x02: + if (ramdac->ctrl & 0x10) { + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + } else + svga_out(addr, val, svga); + break; + case 0x03: + if (ramdac->ctrl & 0x10) + ramdac->idx = val; + else + svga_out(addr, val, svga); + break; + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + break; + case 0x06: + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + break; + + default: + svga_out(addr, val, svga); + break; + } } uint8_t @@ -166,8 +206,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) switch (addr) { case 0x3C6: if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; + temp = ramdac->ctrl; break; } ramdac->state++; @@ -176,7 +215,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 9: temp = 0x53; @@ -203,14 +242,72 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) temp = ramdac->regs[ramdac->idx]; break; } - } else - ramdac->state = 0; + } + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) + if (ramdac->ctrl & 0x10) temp = ramdac->idx; - else - ramdac->state = 0; + + ramdac->state = 0; + break; + + default: + break; + } + + return temp; +} + +uint8_t +sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + uint8_t temp = svga_in(addr, svga); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 9: + temp = 0x53; + break; + case 0x0a: + temp = 0x3a; + break; + case 0x0b: + temp = 0xb1; + break; + case 0x0c: + temp = 0x41; + break; + case 0x0d: + temp = ramdac->pixel_mask & 0xff; + break; + case 0x0e: + temp = ramdac->pixel_mask >> 8; + break; + case 0x0f: + temp = ramdac->pixel_mask >> 16; + break; + default: + temp = ramdac->regs[ramdac->idx]; + break; + } + } + break; + case 0x01: + if (ramdac->ctrl & 0x10) + temp = ramdac->idx; + break; + case 0x02: + if (ramdac->ctrl & 0x10) + temp = ramdac->ctrl; + break; + case 0x06: + temp = ramdac->ctrl; break; default: @@ -221,7 +318,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) } static void * -sc1502x_ramdac_init(UNUSED(const device_t *info)) +sc1502x_ramdac_init(const device_t *info) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); @@ -254,3 +351,17 @@ const device_t sc1502x_ramdac_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sc1502x_rs2_ramdac_device = { + .name = "Sierra SC1502x RAMDAC with RS2", + .internal_name = "sc1502x_rs2_ramdac", + .flags = 0, + .local = 1, + .init = sc1502x_ramdac_init, + .close = sc1502x_ramdac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fbf329e84..870221742 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -49,6 +49,9 @@ #define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" #define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" #define ROM_METHEUS_86C928 "roms/video/s3/928.VBI" +#define ROM_ELSAWIN1KVL_86C928 "roms/video/s3/ELSA_Winner_XHR_1000VL.BIN" +#define ROM_ELSAWIN1KPCI_86C928 "roms/video/s3/ELSA_Winner_10000_PCI_BIOS_3.04.02.BIN" +#define ROM_ELSAWIN2K_86C928 "roms/video/s3/elsa-winner-2000-vga-bios-v1-02-03-66b7554c706d6962736994.bin" #define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" #define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" #define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" @@ -98,6 +101,9 @@ enum { S3_PHOENIX_86C805, S3_ORCHID_86C911, S3_METHEUS_86C928, + S3_ELSAWIN1K_86C928, + S3_ELSAWIN1KPCI_86C928, + S3_ELSAWIN2K_86C928, S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, @@ -191,8 +197,19 @@ enum { FIFO_OUT_DWORD = (0x06 << 24) }; -typedef struct -{ +typedef enum { + BUILT_IN = 0, + SC1148X, + SC1502X, + ATT49X, + ATT498, + BT48X, + IBM_RGB, + S3_SDAC, + TVP3026 +} s3_ramdac_type; + +typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; @@ -204,6 +221,8 @@ typedef struct s3_t { mem_mapping_t new_mmio_mapping; int elsa_eeprom; + s3_ramdac_type ramdac_type; + uint8_t has_bios; rom_t bios_rom; @@ -1519,14 +1538,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xd148: case 0xd2e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; break; case 0xd149: case 0xd2e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); break; case 0xe548: case 0xe6e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); @@ -1537,6 +1559,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe549: case 0xe6e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); @@ -1550,6 +1573,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54a: case 0xe6ea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1561,6 +1585,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54b: case 0xe6eb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1578,7 +1603,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe949: case 0xeae9: - s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x0f) << 8); break; case 0xe94a: case 0xeaea: @@ -1586,10 +1611,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe94b: case 0xeaeb: - s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x0f) << 8); break; case 0xed48: case 0xeee8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); @@ -1600,6 +1626,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed49: case 0xeee9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); @@ -1613,6 +1640,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4a: case 0xeeea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1624,6 +1652,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4b: case 0xeeeb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1977,29 +2006,39 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8120: + addr = 0xa2e8; + break; case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; + addr = 0xa2ea; + break; case 0x8124: + addr = 0xa6e8; + break; case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; + addr = 0xa6ea; + break; case 0x8128: + addr = 0xaae8; + break; case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; + addr = 0xaaea; + break; case 0x812c: + addr = 0xaee8; + break; case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; + addr = 0xaeea; + break; case 0x8130: + addr = 0xb2e8; + break; case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; + addr = 0xb2ea; + break; case 0x8134: addr = 0xb6e8; @@ -2056,9 +2095,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8164: + addr = 0xe6e8; + break; case 0x8166: - WRITE8(addr, s3->accel.pat_bg_color, val); - return; + addr = 0xe6ea; + break; case 0x8168: addr = 0xeae8; @@ -2068,9 +2109,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x816c: + addr = 0xeee8; + break; case 0x816e: - WRITE8(addr, s3->accel.pat_fg_color, val); - return; + addr = 0xeeea; + break; default: break; @@ -2235,7 +2278,7 @@ s3_vblank_start(svga_t *svga) static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { - if ((svga->bpp == 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { + if ((svga->bpp >= 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { if (svga->crtc[0x3a] & 0x10) return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) @@ -3019,27 +3062,38 @@ s3_out(uint16_t addr, uint8_t val, void *priv) else rs2 = (svga->crtc[0x55] & 0x01); // rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - svga_out(addr, val, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && - ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) - att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) { - sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - } else if (s3->card_type == S3_NUMBER9_9FX_531) - att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - else - sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + switch (s3->ramdac_type) { + case BUILT_IN: + default: + svga_out(addr, val, svga); + break; + case SC1148X: + sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case SC1502X: + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + break; + case ATT49X: + att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case ATT498: + att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case BT48X: + rs3 = !!(svga->crtc[0x55] & 0x02); + bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + case IBM_RGB: + ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case S3_SDAC: + sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case TVP3026: + rs3 = !!(svga->crtc[0x55] & 0x02); + tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + } return; case 0x3D4: @@ -3084,7 +3138,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x5c: if (s3->elsa_eeprom) nmc93cxx_eeprom_write(s3->eeprom, !!(val & 0x80), !!(val & 0x40), !!(val & 0x10)); - if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { + if ((s3->card_type == S3_PHOENIX_VISION868) || (s3->card_type == S3_PHOENIX_VISION968)) { if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) svga->dac_addr |= 0x20; } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { @@ -3136,6 +3190,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968)) break; svga->hwcursor.ena = val & 1; + s3_log("Write CRTC45=%02x.\n", val); break; case 0x46: case 0x47: @@ -3213,12 +3268,14 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x55: s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); if (s3->chip == S3_86C928) { - if (val & 0x28) { - svga->hwcursor_draw = NULL; - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - } else { - svga->hwcursor_draw = s3_hwcursor_draw; - svga->dac_hwcursor_draw = NULL; + if (s3->ramdac_type == BT48X) { + if (val & 0x28) { + svga->hwcursor_draw = NULL; + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + } else { + svga->hwcursor_draw = s3_hwcursor_draw; + svga->dac_hwcursor_draw = NULL; + } } } break; @@ -3345,32 +3402,43 @@ s3_in(uint16_t addr, void *priv) case 0x3c8: case 0x3c9: rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - return svga_in(addr, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (s3->chip == S3_86C928) - rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ - else + switch (s3->ramdac_type) { + case BUILT_IN: + default: + temp = svga_in(addr, svga); + break; + case SC1148X: + temp = sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case SC1502X: + temp = sc1502x_ramdac_in(addr, svga->ramdac, svga); + break; + case ATT49X: + temp = att49x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case ATT498: + temp = att498_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case BT48X: + if (s3->chip == S3_86C928) + rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ + else + rs3 = !!(svga->crtc[0x55] & 0x02); + + temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + case IBM_RGB: + temp = ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case S3_SDAC: + temp = sdac_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case TVP3026: rs3 = !!(svga->crtc[0x55] & 0x02); - temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - return temp; - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && - ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) - return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) - return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->card_type == S3_NUMBER9_9FX_531) - return att498_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - return sc1502x_ramdac_in(addr, svga->ramdac, svga); - else - return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; + temp = tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + } + return temp; case 0x3d4: return svga->crtcreg; @@ -3650,20 +3718,21 @@ s3_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); - if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { - if (s3->card_type == S3_ELSAWIN2KPROX_964) - ibm_rgb528_recalctimings(svga->ramdac, svga); - else { + switch (s3->ramdac_type) { + case BT48X: bt48x_recalctimings(svga->ramdac, svga); svga->interlace |= (!!(svga->crtc[0x42] & 0x20)); - } - } else if (s3->chip == S3_VISION968) { - if ((s3->card_type == S3_SPEA_MERCURY_P64V) || (s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) - tvp3026_recalctimings(svga->ramdac, svga); - else + break; + case IBM_RGB: ibm_rgb528_recalctimings(svga->ramdac, svga); - } else - svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + case TVP3026: + tvp3026_recalctimings(svga->ramdac, svga); + break; + default: + svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + } if (s3->chip >= S3_TRIO32) { switch (svga->crtc[0x67] >> 4) { @@ -3797,13 +3866,127 @@ s3_recalctimings(svga_t *svga) break; } break; - + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + if (s3->ramdac_type == BT48X) { + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + } + break; + } + break; + default: + break; + } + break; default: break; } break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -3961,6 +4144,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -3968,6 +4173,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4157,6 +4366,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -4164,6 +4395,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4365,11 +4600,32 @@ s3_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; switch (s3->chip) { + case S3_86C928: + switch (s3->card_type) { + case S3_ELSAWIN1K_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; case S3_VISION864: svga->hdisp >>= 2; svga->dots_per_clock >>= 2; break; - case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: @@ -4499,7 +4755,8 @@ s3_recalctimings(svga_t *svga) } } - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) + if ((((s3->card_type == S3_ELSAWIN1K_86C928) || (s3->card_type == S3_ELSAWIN1KPCI_86C928)) && (svga->bpp == 32)) || + (s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) svga->hoverride = 1; else svga->hoverride = 0; @@ -4771,7 +5028,7 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { if (s3->vlb) s3->linear_base &= 0x03ffffff; - else + else if (!s3->pci) s3->linear_base &= 0x00ffffff; } if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { @@ -7599,6 +7856,7 @@ polygon_setup(s3_t *s3) old_dest_dat = dest_dat; \ ROPMIX_READ(dest_dat, pat_dat, src_dat); \ out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + out &= 0xFFFFFF; \ } #define WRITE(addr, dat) \ @@ -9543,6 +9801,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; case 14: /*ROPBlt (Vision868/968 only)*/ + ; + uint32_t mono_pattern[64] = { 0 }; if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) break; @@ -9552,11 +9812,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; @@ -9567,13 +9823,35 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); s3->accel.pattern = (s3->accel.py * s3->width); + s3_log("ROPBLT=%04x, PIXCntl=%04x, Misc1=%04x, PATBKGDCOL=%08x, PATFRGDCOL=%08x, COLBKGDCOL=%08x, COLFRGDCOL=%08x, PX=%d, PY=%d, DX=%d, DY=%d, CX=%d, CY=%d, FRGDSEL=%x, BKGDSEL=%x, RDMASK=%08x, WRTMASK=%08x, ROPMIX=%03x, pitch=%d.\n", s3->accel.cmd, s3->accel.multifunc[0xa], s3->accel.multifunc[0xe], s3->accel.pat_bg_color, s3->accel.pat_fg_color, s3->accel.bkgd_color, s3->accel.frgd_color, s3->accel.px, s3->accel.py, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, frgd_mix, bkgd_mix, s3->accel.rd_mask, s3->accel.wrt_mask, s3->accel.ropmix, s3->width); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + if (s3->accel.ropmix & 0x100) { + int x; + int y; + switch (s3->accel.cmd & 0x600) { + case 0x000: + case 0x600: + mix_dat &= 0xff; + break; + case 0x200: + mix_dat &= 0xffff; + break; + default: + break; + } + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + mono_pattern[y * 8 + (7 - x)] = (mix_dat & (1 << (x + y * 8))) & 0x80000000; + } + } + } while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = s3->accel.bkgd_color; @@ -9592,24 +9870,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if (s3->accel.ropmix & 0x100) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + if (s3->accel.ropmix & 0x100) { /*Mono pattern used*/ + switch (mono_pattern[(s3->accel.py & 7) * 8 + (s3->accel.px & 7)] ? (frgd_mix & 1) : (bkgd_mix & 1)) { case 0: pat_dat = s3->accel.pat_bg_color; break; case 1: pat_dat = s3->accel.pat_fg_color; break; - case 2: - pat_dat = cpu_dat; - break; - case 3: - READ(s3->accel.pattern + s3->accel.px, pat_dat); - break; - default: break; } + s3_log("MonoMIX=%08x, PX=%d, PY=%d.\n", mix_dat, s3->accel.px & 7, s3->accel.py & 7); } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -9645,19 +9917,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else update = 1; - if (s3->bpp == 2) { - src_dat &= 0xff; - pat_dat &= 0xff; - } else if (s3->bpp == 1) { - src_dat &= 0xffff; - pat_dat &= 0xffff; - } - if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX + s3_log("Destination=%08x, Source=%08x, Pattern=%08x, OUT=%08x, mix=%08x, count=%d.\n", dest_dat, src_dat, pat_dat, out, mix_dat, count); if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, out); } @@ -9666,6 +9931,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; else @@ -10111,6 +10377,21 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_ELSAWIN1K_86C928: + bios_fn = ROM_ELSAWIN1KVL_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_ELSAWIN1KPCI_86C928: + bios_fn = ROM_ELSAWIN1KPCI_86C928; + chip = S3_86C928PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); + break; + case S3_ELSAWIN2K_86C928: + bios_fn = ROM_ELSAWIN2K_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; case S3_SPEA_MERCURY_LITE_PCI: bios_fn = ROM_SPEA_MERCURY_LITE_PCI; chip = S3_86C928PCI; @@ -10482,6 +10763,7 @@ s3_init(const device_t *info) s3->accel_start = s3_accel_start; s3->elsa_eeprom = 0; + s3->ramdac_type = BUILT_IN; switch (s3->card_type) { case S3_ORCHID_86C911: @@ -10494,6 +10776,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; if (s3->card_type == S3_ORCHID_86C911) { svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; @@ -10501,6 +10784,7 @@ s3_init(const device_t *info) /* DCS2824-0 = Diamond ICD2061A-compatible. */ svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } break; @@ -10513,6 +10797,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; @@ -10528,6 +10813,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&gendac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10544,6 +10830,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att491_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; if (info->local == S3_WINNER1000_805) @@ -10560,6 +10847,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att490_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10575,10 +10863,43 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att492_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; + case S3_ELSAWIN1K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + + case S3_ELSAWIN2K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; + svga->clock_gen = device_add(&ics9161_device); + svga->getclock = ics9161_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_METHEUS_86C928: svga->decode_mask = (4 << 20) - 1; stepping = 0x91; /*86C928D*/ @@ -10588,10 +10909,27 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; + case S3_ELSAWIN1KPCI_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0xb0; /*86C928PCI*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_SPEA_MERCURY_LITE_PCI: svga->decode_mask = (4 << 20) - 1; stepping = 0xb0; /*86C928PCI*/ @@ -10601,6 +10939,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10619,6 +10958,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10636,6 +10976,7 @@ s3_init(const device_t *info) switch (info->local) { case S3_ELSAWIN2KPROX_964: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; s3->elsa_eeprom = 1; @@ -10643,8 +10984,10 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); break; } break; @@ -10678,6 +11021,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; if (info->local == S3_ELSAWIN2KPROX) { @@ -10690,6 +11034,7 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&tvp3026_ramdac_device); + s3->ramdac_type = TVP3026; svga->clock_gen = svga->ramdac; svga->getclock = tvp3026_getclock; svga->conv_16to32 = tvp3026_conv_16to32; @@ -10718,10 +11063,13 @@ s3_init(const device_t *info) if (info->local == S3_NUMBER9_9FX_531) { svga->ramdac = device_add(&att498_ramdac_device); + s3->ramdac_type = ATT498; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } else { svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; } @@ -10808,6 +11156,24 @@ s3_init(const device_t *info) s3->eeprom_data[0x08] = 0x83d6; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_805_%d.nvr", s3->eeprom_inst); break; + case S3_ELSAWIN1K_86C928: + s3->eeprom_data[0x02] = 0x0912; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_vlb_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN1KPCI_86C928: + s3->eeprom_data[0x02] = 0x0914; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_pci_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN2K_86C928: + s3->eeprom_data[0x02] = 0x0920; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_928_isa_%d.nvr", s3->eeprom_inst); + break; case S3_ELSAWIN2KPROX: s3->eeprom_data[0x02] = 0x094a; s3->eeprom_data[0x07] = 0xf424; @@ -10910,6 +11276,24 @@ s3_mirocrystal_10sd_805_available(void) return rom_present(ROM_MIROCRYSTAL10SD_805); } +static int +s3_elsa_winner1000_86c928_vlb_available(void) +{ + return rom_present(ROM_ELSAWIN1KVL_86C928); +} + +static int +s3_elsa_winner1000_86c928_pci_available(void) +{ + return rom_present(ROM_ELSAWIN1KPCI_86C928); +} + +static int +s3_elsa_winner2000_86c928_available(void) +{ + return rom_present(ROM_ELSAWIN2K_86C928); +} + static int s3_metheus_86c928_available(void) { @@ -11350,7 +11734,7 @@ const device_t s3_spea_mirage_86c801_isa_device = { }; const device_t s3_winner1000_805_isa_device = { - .name = "S3 86c805 ISA (ELSA Winner 1000)", + .name = "S3 86c805 ISA (ELSA Winner 1000 805i)", .internal_name = "winner1000_805_isa", .flags = DEVICE_ISA16, .local = S3_WINNER1000_805, @@ -11447,6 +11831,34 @@ const device_t s3_phoenix_86c805_vlb_device = { .config = s3_9fx_config }; +const device_t s3_elsa_winner1000_86c928_vlb_device = { + .name = "S3 86c928 VLB (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_vlb", + .flags = DEVICE_VLB, + .local = S3_ELSAWIN1K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_vlb_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + +const device_t s3_elsa_winner2000_86c928_isa_device = { + .name = "S3 86c928 ISA (ELSA Winner 2000 928)", + .internal_name = "elsawin2k928_isa", + .flags = DEVICE_ISA16, + .local = S3_ELSAWIN2K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner2000_86c928_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_metheus_86c928_isa_device = { .name = "S3 86c928 ISA (Metheus Premier 928)", .internal_name = "metheus928_isa", @@ -11475,6 +11887,21 @@ const device_t s3_metheus_86c928_vlb_device = { .config = s3_standard_config }; +const device_t s3_elsa_winner1000_86c928_pci_device = { + .name = "S3 86c928 PCI (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_pci", + .flags = DEVICE_PCI, + .local = S3_ELSAWIN1KPCI_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_pci_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + + const device_t s3_spea_mercury_lite_86c928_pci_device = { .name = "S3 86c928 PCI (SPEA Mercury Lite)", .internal_name = "spea_mercurylite_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index c99f4aad1..20a8f311d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -91,7 +91,6 @@ video_cards[] = { { .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 }, { .device = &oti067_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti077_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -127,10 +126,12 @@ video_cards[] = { { .device = &gd5434_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_diamond_speedstar_64_a3_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &inmos_isa_device, .flags = VIDEO_FLAG_TYPE_XGA }, + { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &radius_svga_multiview_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth_vram_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_orchid_86c911_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_ami_86c924_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner2000_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -160,6 +161,7 @@ video_cards[] = { { .device = &gd5430_diamond_speedstar_pro_se_a8_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5430_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_8s_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_10sd_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -199,6 +201,7 @@ video_cards[] = { { .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_elsa_winner2000_pro_x_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, From d46e2bc8c67d86ab28713b21b8ea2caade5ce15d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Sep 2025 01:12:30 +0200 Subject: [PATCH 03/30] Apply the dynamic SCSI buffer window sizing fix to MO, removable disk, and CD-ROM as well. --- src/disk/mo.c | 11 ++++++++++- src/disk/rdisk.c | 11 ++++++++++- src/include/86box/mo.h | 1 + src/include/86box/rdisk.h | 1 + src/include/86box/scsi_cdrom.h | 1 + src/scsi/scsi_cdrom.c | 15 +++++++++++---- src/scsi/scsi_disk.c | 2 ++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/disk/mo.c b/src/disk/mo.c index b287f68a0..5ffe74f78 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -664,8 +664,17 @@ static void mo_buf_alloc(mo_t *dev, uint32_t len) { mo_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->buffer == NULL) + + if (dev->buffer == NULL) { dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/disk/rdisk.c b/src/disk/rdisk.c index b51dc4e66..683b1e963 100644 --- a/src/disk/rdisk.c +++ b/src/disk/rdisk.c @@ -747,8 +747,17 @@ static void rdisk_buf_alloc(rdisk_t *dev, const uint32_t len) { rdisk_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->buffer == NULL) + + if (dev->buffer == NULL) { dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 6d308adb8..76e7cbdbe 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -140,6 +140,7 @@ typedef struct mo_t { void * log; uint8_t *buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/rdisk.h b/src/include/86box/rdisk.h index df48ba703..c226a2c9d 100644 --- a/src/include/86box/rdisk.h +++ b/src/include/86box/rdisk.h @@ -117,6 +117,7 @@ typedef struct rdisk_t { void *log; uint8_t *buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index c01f347a8..005223e27 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -36,6 +36,7 @@ typedef struct scsi_cdrom_t { void * log; uint8_t * buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index be23a66fe..309886357 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -857,11 +857,18 @@ scsi_cdrom_unit_attention(scsi_cdrom_t *dev) static void scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, const uint32_t len) { - if (dev->buffer == NULL) - dev->buffer = (uint8_t *) malloc(len); + scsi_cdrom_log(dev->log, "Allocated buffer length: %i\n", len); - scsi_cdrom_log(dev->log, "Allocated buffer length: %i, buffer = %p\n", - len, dev->buffer); + if (dev->buffer == NULL) { + dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index bfa8b42cf..9c8d36f7f 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -623,10 +623,12 @@ static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); + if (dev->temp_buffer == NULL) { dev->temp_buffer = (uint8_t *) malloc(len); dev->temp_buffer_sz = len; } + if (len > dev->temp_buffer_sz) { uint8_t *buf = (uint8_t *) realloc(dev->temp_buffer, len); dev->temp_buffer = buf; From 569827ce02f92808b2d8a173fbfbf9ce42acf623 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 7 Sep 2025 14:18:51 +0600 Subject: [PATCH 04/30] MGA: Implement unscaled YUV blits for ILOAD --- src/video/vid_mga.c | 117 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7fdc04e9e..564136428 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3598,6 +3598,12 @@ dither_24_to_8(int r, int g, int b) return ((b >> 6) & 3) | (((g >> 5) & 7) << 2) | (((r >> 5) & 7) << 5); } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) + static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { @@ -3613,7 +3619,50 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; uint32_t data_mask = 1; + /* YUV stuff */ + int y0; + int y1; + int u; + int v; + int dR; + int dG; + int dB; + int r0; + int g0; + int b0; + int r1; + int g1; + int b1; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int) (data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int) ((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; + + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); + + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t) b1 << 32) | ((uint64_t) g1 << 40) | ((uint64_t) r1 << 48); + size = 64; + + break; + } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: bltckey &= 0xff; @@ -3947,6 +3996,65 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) mystique->dwgreg.iload_rem_data = data64; break; + case DWGCTRL_BLTMOD_BUYUV: + while (size >= 32) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + { + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(dither(mystique, (data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF, mystique->dwgreg.xdst & 1, mystique->dwgreg.selline & 1), dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + } + case MACCESS_PWIDTH_8: + { + dst = ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(dither_24_to_8((data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF), dst, mystique->dwgreg.dwgctrl_running); + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + } + default: { + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + } + } + } + + size -= 32; + data64 >>= 32ULL; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + case DWGCTRL_BLTMOD_BU32BGR: size += mystique->dwgreg.iload_rem_count; while (size >= 32) { @@ -3996,12 +4104,6 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) } } -#define CLAMP(x) \ - do { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } while (0) - static void blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) { @@ -4053,7 +4155,7 @@ blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) break; case MACCESS_PWIDTH_32: data64 = b0 | (g0 << 8) | (r0 << 16); - data64 |= ((uint64_t) b0 << 32) | ((uint64_t) g0 << 40) | ((uint64_t) r0 << 48); + data64 |= ((uint64_t) b1 << 32) | ((uint64_t) g1 << 40) | ((uint64_t) r1 << 48); size = 64; break; @@ -5925,6 +6027,7 @@ blit_iload(mystique_t *mystique) case DWGCTRL_BLTMOD_BMONOWF: case DWGCTRL_BLTMOD_BU24RGB: case DWGCTRL_BLTMOD_BU32RGB: + case DWGCTRL_BLTMOD_BUYUV: mystique->dwgreg.length_cur = mystique->dwgreg.length; mystique->dwgreg.xdst = mystique->dwgreg.fxleft; mystique->dwgreg.iload_rem_data = 0; From b74c513273f2a5264faf621422ce85bcbbe0a4aa Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 7 Sep 2025 18:01:37 +0600 Subject: [PATCH 05/30] Adjust `scsi_common_t` structure definition to match the rest (#6133) Fixes https://github.com/86Box/86Box/issues/6131 --- src/include/86box/scsi_device.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 289201b04..d5d620670 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -388,6 +388,7 @@ typedef struct scsi_common_s { void * log; uint8_t * temp_buffer; + size_t temp_buffer_sz; /* This is atapi_cdb in ATAPI-supporting devices, and pad in SCSI-only devices. From a13bc2d532ef8af8e61b708633b081b075121313 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Sep 2025 23:31:07 +0200 Subject: [PATCH 06/30] EGA: Remove an excess logging line. --- src/video/vid_ega.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index e96bd827c..d25861681 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -149,7 +149,6 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->vres = !(val & 0x80); ega->pallook = ega->vres ? pallook16 : pallook64; ega->vidclock = val & 4; - pclog("clock = %01X\n", (val & 0x0c) >> 2); ega->miscout = val; ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; From f3b18ef8bf242ebb63f804f588a1b5e1b774324b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Sep 2025 23:38:36 +0200 Subject: [PATCH 07/30] Restore the obsolete pause resume alt opcode. As a redirect to the SCSI Pause/Resume 0x4B command. --- src/scsi/scsi_cdrom.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 309886357..f5b81e369 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -472,7 +472,7 @@ scsi_cdrom_mode_sense_read(const scsi_cdrom_t *dev, const uint8_t pgctl, default: break; - } + } return ret; } @@ -1579,7 +1579,7 @@ scsi_cdrom_read(scsi_common_t *sc) dev->drv->seek_diff = 0; if (ret > 0) { - if (osl > 0) + if (osl > 0) scsi_cdrom_set_period(dev); ui_sb_update_icon(SB_CDROM | dev->id, @@ -2626,7 +2626,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) dev->sector_type, 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (6): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2639,7 +2639,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) (cdb[9] & 0xc0) : 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (10): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2655,7 +2655,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) (cdb[9] & 0xc0) : 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (12): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2706,7 +2706,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) scsi_cdrom_buf_alloc(dev, dev->packet_len); dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); - dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_pos = dev->sector_pos; /* Any of these commands stop the audio playing. */ cdrom_stop(dev->drv); @@ -3524,6 +3524,7 @@ atapi_out: break; case GPCMD_PAUSE_RESUME: + case GPCMD_PAUSE_RESUME_ALT: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); scsi_cdrom_command_complete(dev); From 63a78e388b270ed5e24f55ca347110bfb210606a Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Sep 2025 01:38:46 +0200 Subject: [PATCH 08/30] Olivetti M19: Use the 3.71 BIOS instead, because it's newer. --- src/machine/m_xt_olivetti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 079cd4555..13d98e6f9 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -2426,7 +2426,7 @@ machine_xt_m19_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/m19/BIOS.BIN", + ret = bios_load_linear("roms/machines/m19/Olivetti M19 Resident Diagnostics Rev 3.71.BIN", 0x000fc000, 16384, 0); ret &= rom_present("roms/machines/m19/MBM2764-30 8514 107 AB PCF3.BIN"); From 845d1ddc4388b67a94497484ca5d9bb392b0b9ac Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 8 Sep 2025 11:23:08 +0700 Subject: [PATCH 09/30] Added two baud rates (28.8k and 33.6k) According to Windows 98 modem setup. --- src/network/net_modem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index af97a16db..24869349f 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1566,6 +1566,8 @@ static const device_config_t modem_config[] = { { .description = "57600", .value = 57600 }, { .description = "56000", .value = 56000 }, { .description = "38400", .value = 38400 }, + { .description = "33600", .value = 33600 }, + { .description = "28800", .value = 28800 }, { .description = "19200", .value = 19200 }, { .description = "14400", .value = 14400 }, { .description = "9600", .value = 9600 }, From 22ba8b32c138ea9a4931522b7f83d5ad778ac8b5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 8 Sep 2025 15:37:11 +0600 Subject: [PATCH 10/30] Add support for Trio3D/2X's 8-bit palette DAC --- src/video/vid_s3_virge.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 3bd6d694d..d8356df4a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -828,6 +828,9 @@ s3_virge_recalctimings(svga_t *svga) svga->hdisp = svga->hdisp_old; + if (virge->chip >= S3_TRIO3D2X) { + svga_set_ramdac_type(svga, (svga->seqregs[0x1b] & 0x10) ? RAMDAC_8BIT : RAMDAC_6BIT); + } if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) { /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); From 84d96271dee2de8c83284181819d34fb64961c6b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Sep 2025 22:27:39 +0200 Subject: [PATCH 11/30] Implement the Super MegaZeux text mode. --- src/video/vid_svga_render.c | 70 +++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index f43db41c4..9afae254d 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -243,6 +243,8 @@ svga_render_text_80(svga_t *svga) p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; + uint32_t col = 0x00000000; + for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) addr = svga->remap_func(svga, svga->memaddr) & svga->vram_display_mask; @@ -263,30 +265,70 @@ svga_render_text_80(svga_t *svga) charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; - fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; + bg = attr & 15; + fg = attr >> 4; } else { - fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; - bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; + fg = attr & 15; + bg = attr >> 4; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; + bg = (attr >> 4) & 7; if (svga->blink & 16) fg = bg; } } dat = svga->vram[charaddr + (svga->scanline << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + + if (svga->attrregs[0x10] & 0x40) { + pclog("256-color text mode\n"); + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) { + uint32_t col16 = (dat & (0x80 >> xx)) ? fg : bg; + if ((x + xx - svga->scrollcache) & 1) { + col |= col16; + if ((x + xx - 1) >= 0) + p[xx - 1] = svga->pallook[col & svga->dac_mask]; + if ((x + xx) >= 0) + p[xx] = svga->pallook[col & svga->dac_mask]; + } else + col = col16 << 4; + } + } else { + for (xx = 0; xx < 9; xx++) { + uint32_t col16; + if (xx < 8) + col16 = (dat & (0x80 >> xx)) ? fg : bg; + else if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + col16 = bg; + else + col16 = (dat & 1) ? fg : bg; + if ((x + xx - svga->scrollcache) & 1) { + col |= col16; + if ((x + xx - 1) >= 0) + p[xx - 1] = svga->pallook[col & svga->dac_mask]; + if ((x + xx) >= 0) + p[xx] = svga->pallook[col & svga->dac_mask]; + } else + col = col16 << 4; + } + } } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; + fg = svga->pallook[svga->egapal[fg] & svga->dac_mask]; + bg = svga->pallook[svga->egapal[bg] & svga->dac_mask]; + + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } } + svga->memaddr += 4; p += xinc; } From 8bb6444c7a66043e6176f6be0121f71d0e877bb4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 8 Sep 2025 22:59:34 +0200 Subject: [PATCH 12/30] Latest video fixes of the day (September 8th, 2025) On soft-reset, reset the Misc Multifunc (0x0D/0x0E) values to sane defaults per manuals. --- src/video/vid_s3.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 870221742..5b9626ad9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -5025,12 +5025,13 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928) { s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (s3->chip <= S3_86C805) { if (s3->vlb) s3->linear_base &= 0x03ffffff; else if (!s3->pci) s3->linear_base &= 0x00ffffff; } + if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); @@ -10263,8 +10264,10 @@ s3_reset(void *priv) s3_t *s3 = (s3_t *) priv; if (reset_state != NULL) { - s3->accel.multifunc[0xe] &= ~(0x200 | 0x10); s3_disable_handlers(s3); + s3->accel.multifunc[0xd] = 0xd000; + s3->accel.multifunc[0xe] = 0xe000; + s3_log("S3 reset done.\n"); s3->force_busy = 0; s3->blitter_busy = 0; s3->fifo_read_idx = 0; @@ -10273,7 +10276,8 @@ s3_reset(void *priv) reset_state->pci_slot = s3->pci_slot; *s3 = *reset_state; - } + } else + s3_log("NULL reset.\n"); } static uint16_t From 3a703d0c0d1f8c2c23846b92849eb8eef9826466 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Sep 2025 00:18:14 +0200 Subject: [PATCH 13/30] Last minute changes for the high color S3 911/924 mode Read mask initialized to 0xff allows proper colors on initial boot of Windows. --- src/video/vid_s3.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 5b9626ad9..53f75365f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -830,6 +830,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { svga_t *svga = &s3->svga; + s3_log("OUTB FIFO=%04x, val=%02x.\n", port, val); switch (port) { case 0x8148: case 0x82e8: @@ -8807,6 +8808,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + s3_log("CMD2: RDMASK16CHECK=%d, rdmask=%04x.\n", s3->accel.rd_mask_16bit_check, rd_mask); if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cmd == 0x41b3) { if (frgd_mix == 0) { @@ -9211,6 +9213,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + s3_log("CMD6: RDMASK16CHECK=%d.\n", s3->accel.rd_mask_16bit_check); if (s3->accel.rd_mask_16bit_check) { if (!(clip_r & 0x400)) s3->accel.start = 1; @@ -10778,6 +10781,7 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; + s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); s3->ramdac_type = SC1148X; @@ -10799,6 +10803,7 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; + s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); s3->ramdac_type = SC1148X; From 91d7bb38390cb8458ed906bd4cc112543089e329 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Sep 2025 01:29:47 +0200 Subject: [PATCH 14/30] (S)VGA render: remove an excess logging line. --- src/video/vid_svga_render.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 9afae254d..5e4844aed 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -280,7 +280,6 @@ svga_render_text_80(svga_t *svga) dat = svga->vram[charaddr + (svga->scanline << 2)]; if (svga->attrregs[0x10] & 0x40) { - pclog("256-color text mode\n"); if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) { uint32_t col16 = (dat & (0x80 >> xx)) ? fg : bg; From 430627e77669e82724bce66991872640db660a20 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 10:11:48 +0800 Subject: [PATCH 15/30] fix file handler typo in line #422 --- src/minitrace/minitrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/minitrace/minitrace.c b/src/minitrace/minitrace.c index 290486ec5..9762f1c55 100644 --- a/src/minitrace/minitrace.c +++ b/src/minitrace/minitrace.c @@ -419,7 +419,7 @@ void mtr_flush_with_state(int is_last) { len = snprintf(linebuf, ARRAY_SIZE(linebuf), "%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}", first_line ? "" : ",\n", cat, raw->pid, raw->tid, raw->ts - time_offset, raw->ph, raw->name, arg_buf, id_buf); - fwrite(linebuf, 1, len, f); + fwrite(linebuf, 1, len, fp); first_line = 0; if (raw->arg_type == MTR_ARG_TYPE_STRING_COPY) { From fb64862fcffc994d1e4666c773a6ee06f74b10a5 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 12:33:52 +0800 Subject: [PATCH 16/30] rename machine 'Multitech PC-500' to 'Multitech PC-500 plus' --- src/include/86box/machine.h | 2 +- src/machine/m_xt.c | 4 ++-- src/machine/machine_table.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 7ab675a6c..6eecb9f49 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1319,7 +1319,7 @@ extern const device_t jukopc_device; extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_kaypropc_init(const machine_t *); extern int machine_xt_micoms_xl7turbo_init(const machine_t *); -extern int machine_xt_pc500_init(const machine_t *); +extern int machine_xt_pc500plus_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc4i_init(const machine_t *); extern int machine_xt_openxt_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 954483d62..b909857d1 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -975,12 +975,12 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) } int -machine_xt_pc500_init(const machine_t *model) +machine_xt_pc500plus_init(const machine_t *model) { int ret; ret = bios_load_linear("roms/machines/pc500/rom404.bin", - 0x000f8000, 32768, 0); + 0x000fc000, 16384, 0); if (bios_only || !ret) return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7891bb3db..ec5f2e9f0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1095,11 +1095,11 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Multitech PC-500", - .internal_name = "pc500", + .name = "[8088] Multitech PC-500 plus", + .internal_name = "pc500plus", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc500_init, + .init = machine_xt_pc500plus_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From a5a9ca148e2ef48da7884daf11abbd39fe64afab Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 12:39:41 +0800 Subject: [PATCH 17/30] add machine Multitech PC-500 with BIOS ROM v3.10 and v3.30 --- src/include/86box/machine.h | 4 ++ src/machine/m_xt.c | 75 +++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 43 +++++++++++++++++++++ 3 files changed, 122 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6eecb9f49..b2520976e 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1319,6 +1319,10 @@ extern const device_t jukopc_device; extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_kaypropc_init(const machine_t *); extern int machine_xt_micoms_xl7turbo_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pc500_device; +#endif +extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_pc500plus_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc4i_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index b909857d1..815045389 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -974,6 +974,81 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) return ret; } +static const device_config_t pc500_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pc500_330", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "3.30", + .internal_name = "pc500_330", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc500/rom330.bin", "" } + }, + { + .name = "3.10", + .internal_name = "pc500_310", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc500/rom310.bin", "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pc500_device = { + .name = "Multitech PC-500", + .internal_name = "pc500_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pc500_config +}; + +int +machine_xt_pc500_init(const machine_t *model) +{ + int ret = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 8192, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + device_add(&kbc_pc_device); + + machine_xt_common_init(model, 0); + + return ret; +} + int machine_xt_pc500plus_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ec5f2e9f0..8f6d20a27 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1094,6 +1094,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] Multitech PC-500", + .internal_name = "pc500", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pc500_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_pc_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pc500_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Multitech PC-500 plus", .internal_name = "pc500plus", From 32555f0edb61b434acaf9cd890bc6ae227ed9cf6 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 13:03:18 +0800 Subject: [PATCH 18/30] add machine 'Multitech PC-900' --- src/include/86box/machine.h | 1 + src/machine/m_at_286.c | 21 ++++++++++++++++++ src/machine/machine_table.c | 44 +++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b2520976e..6de1586dc 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -498,6 +498,7 @@ extern int machine_at_cmdpc_init(const machine_t *); extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_grid1520_init(const machine_t *); +extern int machine_at_mpfpc900_init(const machine_t *); extern int machine_at_mr286_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_m290_init(const machine_t *); diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index f74ad5115..a1b71a817 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -328,6 +328,27 @@ machine_at_grid1520_init(const machine_t *model) { return ret; } +int +machine_at_mpfpc900_init(const machine_t *model) { + int ret = 0; + + ret = bios_load_linear("roms/machines/pc900/mpf_pc900_v207a.bin", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + + mem_remap_top(384); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_mr286_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8f6d20a27..20baadfcf 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3343,6 +3343,50 @@ const machine_t machines[] = { .net_device = NULL }, /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Multitech PC-900", + .internal_name = "mpfpc900", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_mpfpc900_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 6000000, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 1024, + .step = 128 + }, + .nvrmask = 63, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ { .name = "[ISA] MR BIOS 286 clone", .internal_name = "mr286", From 51c23289499b4dbc8b707f45dd7670862796144b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Sep 2025 20:11:59 +0200 Subject: [PATCH 19/30] (S)VGA: Implement odd pel shifts in 256-color modes. --- src/include/86box/vid_svga.h | 1 + src/video/vid_svga.c | 9 +++++++-- src/video/vid_svga_render.c | 25 ++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index a66dd8c03..cbd6c511a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -141,6 +141,7 @@ typedef struct svga_t { int render_line_offset; int start_retrace_latch; int vga_mode; + int half_pixel; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 302a26f23..d3a95f0bb 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1480,6 +1480,7 @@ svga_poll(void *priv) svga->scanline = 0; if (svga->attrregs[0x10] & 0x20) { svga->scrollcache = 0; + svga->half_pixel = 0; svga->x_add = svga->left_overscan; } } @@ -1580,11 +1581,15 @@ svga_poll(void *priv) if (svga->scrollcache > 8) svga->scrollcache = 0; } + svga->half_pixel = 0; } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || - (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; svga->scrollcache &= 0x07; - else + } else { + svga->half_pixel = svga->scrollcache & 0x01; svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) svga->scrollcache <<= 1; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 5e4844aed..773874322 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -805,6 +805,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t incr_counter = 0; uint32_t load_counter = 0; uint32_t edat = 0; + uint32_t col = 0; + uint32_t col2 = 0; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) { if (load_counter == 0) { /* Find our address */ @@ -923,8 +925,19 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } else if (combine8bits) { if (svga->packed_4bpp) { - uint32_t p0 = svga->map8[c0 & svga->dac_mask]; - uint32_t p1 = svga->map8[c1 & svga->dac_mask]; + uint32_t p0; + uint32_t p1; + if (svga->half_pixel) { + col |= (c0 >> 4) & 0xff; + col2 = (c0 << 4) & 0xff; + col2 |= (c1 >> 4) & 0xff; + p0 = svga->map8[col & svga->dac_mask]; + p1 = svga->map8[col2 & svga->dac_mask]; + col = (c1 << 4) & 0xff; + } else { + p0 = svga->map8[c0 & svga->dac_mask]; + p1 = svga->map8[c1 & svga->dac_mask]; + } const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -932,7 +945,13 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx + dotwidth] = p1; } else { uint32_t ccombined = (c0 << 4) | c1; - uint32_t p0 = svga->map8[ccombined & svga->dac_mask]; + uint32_t p0; + if (svga->half_pixel) { + col |= (ccombined >> 4) & 0xff; + p0 = svga->map8[col & svga->dac_mask]; + col = (ccombined << 4) & 0xff; + } else + p0 = svga->map8[ccombined & svga->dac_mask]; const int outoffs = (i >> 1) << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; From e630a8fa25f3b80d81776a1fa3fc2985a83e0309 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Sep 2025 21:50:49 +0200 Subject: [PATCH 20/30] (S)VGA: Implement some level of pel shift memorization. --- src/video/vid_svga_render.c | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 773874322..92228243f 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -243,7 +243,7 @@ svga_render_text_80(svga_t *svga) p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; - uint32_t col = 0x00000000; + static uint32_t col = 0x00000000; for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) @@ -312,19 +312,21 @@ svga_render_text_80(svga_t *svga) } } } else { - fg = svga->pallook[svga->egapal[fg] & svga->dac_mask]; - bg = svga->pallook[svga->egapal[bg] & svga->dac_mask]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + for (xx = 0; xx < 8; xx++) { + col = (col << 4) | ((dat & (0x80 >> xx)) ? fg : bg); + p[xx] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + for (xx = 0; xx < 8; xx++) { + col = (col << 4) | ((dat & (0x80 >> xx)) ? fg : bg); + p[xx] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; + col = (col << 4) | bg; else - p[8] = (dat & 1) ? fg : bg; + col = (col << 4) | ((dat & 1) ? fg : bg); + p[8] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; } } @@ -805,8 +807,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t incr_counter = 0; uint32_t load_counter = 0; uint32_t edat = 0; - uint32_t col = 0; - uint32_t col2 = 0; + static uint32_t col = 0; + static uint32_t col2 = 0; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) { if (load_counter == 0) { /* Find our address */ @@ -928,6 +930,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t p0; uint32_t p1; if (svga->half_pixel) { + col &= 0xf0; col |= (c0 >> 4) & 0xff; col2 = (c0 << 4) & 0xff; col2 |= (c1 >> 4) & 0xff; @@ -937,6 +940,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } else { p0 = svga->map8[c0 & svga->dac_mask]; p1 = svga->map8[c1 & svga->dac_mask]; + col = p1; } const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) @@ -947,11 +951,14 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t ccombined = (c0 << 4) | c1; uint32_t p0; if (svga->half_pixel) { + col &= 0xf0; col |= (ccombined >> 4) & 0xff; p0 = svga->map8[col & svga->dac_mask]; col = (ccombined << 4) & 0xff; - } else + } else { p0 = svga->map8[ccombined & svga->dac_mask]; + col = p0; + } const int outoffs = (i >> 1) << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -964,6 +971,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx] = p0; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx + dotwidth] = p1; + if ((x + i - svga->scrollcache) & 0x01) + /* The lower 4 bits are undefined at this point. */ + col = c1 << 4; + else + col = (c0 << 4) | c1; } } From 3a67c54687078255abbdb1c3b5e917ca65c691fc Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Sep 2025 23:07:29 +0200 Subject: [PATCH 21/30] Overriding changes (September 9th, 2025) Dealing with 3D card overriding with XGA/IBM 8514/A compatibles again... --- src/video/vid_8514a.c | 230 +++++++++++++++++++++-------------------- src/video/vid_xga.c | 234 +++++++++++++++++++++--------------------- 2 files changed, 236 insertions(+), 228 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 32a402ec5..7b747ddc0 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -3674,143 +3674,147 @@ ibm8514_poll(void *priv) ibm8514_log("IBM 8514/A poll=%x offtime=%" PRIu64 ", ontime=%" PRIu64 ".\n", dev->on, dev->dispofftime, dev->dispontime); if (dev->on) { ibm8514_log("ON!\n"); - if (!dev->linepos) { - if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; - dev->hwcursor_oddeven = 0; - } - - if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); - dev->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, dev->dispofftime); - svga->cgastat |= 1; - dev->linepos = 1; - - if (dev->dispon) { - dev->hdisp_on = 1; - - dev->memaddr &= dev->vram_mask; - - if (dev->firstline == 2000) { - dev->firstline = dev->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + if (svga->override) + svga_set_poll(svga); + else { + if (!dev->linepos) { + if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; + dev->hwcursor_oddeven = 0; } - if (dev->hwcursor_on) - dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; + if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); + dev->hwcursor_oddeven = 1; + } - svga->render8514(svga); + timer_advance_u64(&svga->timer, dev->dispofftime); + svga->cgastat |= 1; + dev->linepos = 1; - svga->x_add = svga->left_overscan; - ibm8514_render_overscan_left(dev, svga); - ibm8514_render_overscan_right(dev, svga); - svga->x_add = svga->left_overscan; + if (dev->dispon) { + dev->hdisp_on = 1; - if (dev->hwcursor_on) { - if (svga->hwcursor_draw) - svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); - dev->hwcursor_on--; - if (dev->hwcursor_on && dev->interlace) + dev->memaddr &= dev->vram_mask; + + if (dev->firstline == 2000) { + dev->firstline = dev->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (dev->hwcursor_on) + dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; + + svga->render8514(svga); + + svga->x_add = svga->left_overscan; + ibm8514_render_overscan_left(dev, svga); + ibm8514_render_overscan_right(dev, svga); + svga->x_add = svga->left_overscan; + + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); dev->hwcursor_on--; + if (dev->hwcursor_on && dev->interlace) + dev->hwcursor_on--; + } + + if (dev->lastline < dev->displine) + dev->lastline = dev->displine; } - if (dev->lastline < dev->displine) - dev->lastline = dev->displine; - } - - dev->displine++; - if (dev->interlace) dev->displine++; - if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - svga->vslines++; - if (dev->displine > 2000) - dev->displine = 0; - } else { - timer_advance_u64(&svga->timer, dev->dispontime); - if (dev->dispon) - svga->cgastat &= ~1; - dev->hdisp_on = 0; + if (dev->interlace) + dev->displine++; + if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; + if (dev->displine > 2000) + dev->displine = 0; + } else { + timer_advance_u64(&svga->timer, dev->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; + dev->hdisp_on = 0; - dev->linepos = 0; - if (dev->dispon) { - if (dev->scanline == dev->rowcount) { - dev->scanline = 0; - dev->memaddr_backup += (dev->rowoffset << 3); - if (dev->interlace) + dev->linepos = 0; + if (dev->dispon) { + if (dev->scanline == dev->rowcount) { + dev->scanline = 0; dev->memaddr_backup += (dev->rowoffset << 3); + if (dev->interlace) + dev->memaddr_backup += (dev->rowoffset << 3); - dev->memaddr_backup &= dev->vram_mask; - dev->memaddr = dev->memaddr_backup; - } else { - dev->scanline++; - dev->scanline &= 0x1f; - dev->memaddr = dev->memaddr_backup; - } - } - - dev->vc++; - dev->vc &= 0xfff; - - if (dev->vc == dev->dispend) { - dev->vblank_start(svga); - ibm8514_log("VBLANK irq.\n"); - dev->dispon = 0; - - for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { - if (dev->changedvram[x]) - dev->changedvram[x]--; + dev->memaddr_backup &= dev->vram_mask; + dev->memaddr = dev->memaddr_backup; + } else { + dev->scanline++; + dev->scanline &= 0x1f; + dev->memaddr = dev->memaddr_backup; + } } - if (svga->fullchange) - svga->fullchange--; - } - if (dev->vc == dev->v_syncstart) { - dev->dispon = 0; - svga->cgastat |= 8; - x = dev->h_disp; + dev->vc++; + dev->vc &= 0xfff; - if (dev->interlace && !dev->oddeven) - dev->lastline++; - if (dev->interlace && dev->oddeven) - dev->firstline--; + if (dev->vc == dev->dispend) { + dev->vblank_start(svga); + ibm8514_log("VBLANK irq.\n"); + dev->dispon = 0; - wx = x; - wy = dev->lastline - dev->firstline; - svga_doblit(wx, wy, svga); + for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { + if (dev->changedvram[x]) + dev->changedvram[x]--; + } - dev->firstline = 2000; - dev->lastline = 0; + if (svga->fullchange) + svga->fullchange--; + } + if (dev->vc == dev->v_syncstart) { + dev->dispon = 0; + svga->cgastat |= 8; + x = dev->h_disp; - dev->firstline_draw = 2000; - dev->lastline_draw = 0; + if (dev->interlace && !dev->oddeven) + dev->lastline++; + if (dev->interlace && dev->oddeven) + dev->firstline--; - dev->oddeven ^= 1; + wx = x; + wy = dev->lastline - dev->firstline; + svga_doblit(wx, wy, svga); - svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; - svga->vslines = 0; + dev->firstline = 2000; + dev->lastline = 0; - if (dev->interlace && dev->oddeven) - dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); - else - dev->memaddr = dev->memaddr_backup = 0; + dev->firstline_draw = 2000; + dev->lastline_draw = 0; - dev->memaddr = (dev->memaddr << 2); - dev->memaddr_backup = (dev->memaddr_backup << 2); - } - if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->scanline = (svga->crtc[0x8] & 0x1f); - dev->dispon = 1; - dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + dev->oddeven ^= 1; - svga->x_add = svga->left_overscan; + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; - dev->hwcursor_on = 0; - dev->hwcursor_latch = dev->hwcursor; + if (dev->interlace && dev->oddeven) + dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); + else + dev->memaddr = dev->memaddr_backup = 0; + + dev->memaddr = (dev->memaddr << 2); + dev->memaddr_backup = (dev->memaddr_backup << 2); + } + if (dev->vc == dev->v_total) { + dev->vc = 0; + dev->scanline = (svga->crtc[0x8] & 0x1f); + dev->dispon = 1; + dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + + svga->x_add = svga->left_overscan; + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; + } } } } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index a91a893df..8de29a2e6 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -3303,152 +3303,156 @@ xga_poll(void *priv) xga_log("XGA Poll=%d.\n", xga->on); if (xga->on) { - if (!xga->linepos) { - if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); - xga->hwcursor_oddeven = 0; - } - - if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); - xga->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, xga->dispofftime); - svga->cgastat |= 1; - xga->linepos = 1; - - if (xga->dispon) { - xga->h_disp_on = 1; - - xga->memaddr &= xga->vram_mask; - - if (xga->firstline == 2000) { - xga->firstline = xga->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + if (svga->override) + svga_set_poll(svga); + else { + if (!xga->linepos) { + if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); + xga->hwcursor_oddeven = 0; } - if (xga->hwcursor_on) - xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; + if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); + xga->hwcursor_oddeven = 1; + } - svga->render_xga(svga); + timer_advance_u64(&svga->timer, xga->dispofftime); + svga->cgastat |= 1; + xga->linepos = 1; - svga->x_add = svga->left_overscan; - xga_render_overscan_left(xga, svga); - xga_render_overscan_right(xga, svga); - svga->x_add = svga->left_overscan; + if (xga->dispon) { + xga->h_disp_on = 1; - if (xga->hwcursor_on) { - xga_hwcursor_draw(svga, xga->displine + svga->y_add); - xga->hwcursor_on--; - if (xga->hwcursor_on && xga->interlace) + xga->memaddr &= xga->vram_mask; + + if (xga->firstline == 2000) { + xga->firstline = xga->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (xga->hwcursor_on) + xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; + + svga->render_xga(svga); + + svga->x_add = svga->left_overscan; + xga_render_overscan_left(xga, svga); + xga_render_overscan_right(xga, svga); + svga->x_add = svga->left_overscan; + + if (xga->hwcursor_on) { + xga_hwcursor_draw(svga, xga->displine + svga->y_add); xga->hwcursor_on--; + if (xga->hwcursor_on && xga->interlace) + xga->hwcursor_on--; + } + + if (xga->lastline < xga->displine) + xga->lastline = xga->displine; } - if (xga->lastline < xga->displine) - xga->lastline = xga->displine; - } - - xga->displine++; - if (xga->interlace) xga->displine++; - if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - if (xga->displine > 1500) - xga->displine = 0; - } else { - timer_advance_u64(&svga->timer, xga->dispontime); - if (xga->dispon) - svga->cgastat &= ~1; + if (xga->interlace) + xga->displine++; + if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + if (xga->displine > 1500) + xga->displine = 0; + } else { + timer_advance_u64(&svga->timer, xga->dispontime); + if (xga->dispon) + svga->cgastat &= ~1; - xga->h_disp_on = 0; + xga->h_disp_on = 0; - xga->linepos = 0; - if (xga->dispon) { - if (xga->scanline == xga->rowcount) { - xga->scanline = 0; + xga->linepos = 0; + if (xga->dispon) { + if (xga->scanline == xga->rowcount) { + xga->scanline = 0; - xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); - xga->memaddr_backup += (xga->rowoffset << 3); - if (xga->interlace) + xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); xga->memaddr_backup += (xga->rowoffset << 3); + if (xga->interlace) + xga->memaddr_backup += (xga->rowoffset << 3); - xga->memaddr_backup &= xga->vram_mask; - xga->memaddr = xga->memaddr_backup; - } else { - xga->scanline++; - xga->scanline &= 0x1f; - xga->memaddr = xga->memaddr_backup; + xga->memaddr_backup &= xga->vram_mask; + xga->memaddr = xga->memaddr_backup; + } else { + xga->scanline++; + xga->scanline &= 0x1f; + xga->memaddr = xga->memaddr_backup; + } } - } - xga->vc++; - xga->vc &= 0x7ff; + xga->vc++; + xga->vc &= 0x7ff; - if (xga->vc == xga->split) { - if (xga->interlace && xga->oddeven) - xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); - else - xga->memaddr = xga->memaddr_backup = 0; + if (xga->vc == xga->split) { + if (xga->interlace && xga->oddeven) + xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); + else + xga->memaddr = xga->memaddr_backup = 0; - xga->memaddr = (xga->memaddr << 2); - xga->memaddr_backup = (xga->memaddr_backup << 2); + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); - xga->scanline = 0; - } - if (xga->vc == xga->dispend) { - xga->dispon = 0; - - for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { - if (xga->changedvram[x]) - xga->changedvram[x]--; + xga->scanline = 0; } - if (svga->fullchange) - svga->fullchange--; - } - if (xga->vc == xga->v_syncstart) { - xga->dispon = 0; - svga->cgastat |= 8; - x = xga->h_disp; + if (xga->vc == xga->dispend) { + xga->dispon = 0; - if (xga->interlace && !xga->oddeven) - xga->lastline++; - if (xga->interlace && xga->oddeven) - xga->firstline--; + for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { + if (xga->changedvram[x]) + xga->changedvram[x]--; + } + if (svga->fullchange) + svga->fullchange--; + } + if (xga->vc == xga->v_syncstart) { + xga->dispon = 0; + svga->cgastat |= 8; + x = xga->h_disp; - wx = x; + if (xga->interlace && !xga->oddeven) + xga->lastline++; + if (xga->interlace && xga->oddeven) + xga->firstline--; - wy = xga->lastline - xga->firstline; - svga_doblit(wx, wy, svga); + wx = x; - xga->firstline = 2000; - xga->lastline = 0; + wy = xga->lastline - xga->firstline; + svga_doblit(wx, wy, svga); - xga->firstline_draw = 2000; - xga->lastline_draw = 0; + xga->firstline = 2000; + xga->lastline = 0; - xga->oddeven ^= 1; + xga->firstline_draw = 2000; + xga->lastline_draw = 0; - svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; + xga->oddeven ^= 1; - if (xga->interlace && xga->oddeven) - xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); - else - xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; + svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; - xga->memaddr = (xga->memaddr << 2); - xga->memaddr_backup = (xga->memaddr_backup << 2); - } - if (xga->vc == xga->v_total) { - xga->vc = 0; - xga->scanline = 0; - xga->dispon = 1; - xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; + if (xga->interlace && xga->oddeven) + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); + else + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; - svga->x_add = svga->left_overscan; + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); + } + if (xga->vc == xga->v_total) { + xga->vc = 0; + xga->scanline = 0; + xga->dispon = 1; + xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; - xga->hwcursor_on = 0; - xga->hwcursor_latch = xga->hwcursor; + svga->x_add = svga->left_overscan; + + xga->hwcursor_on = 0; + xga->hwcursor_latch = xga->hwcursor; + } } } } else From 60d502daad92bcf4e1a8c17810c1bf14f2f9b6fe Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Sep 2025 00:28:05 +0200 Subject: [PATCH 22/30] (S)VGA pel panning: values above 7 behave like 7. --- src/video/vid_svga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d3a95f0bb..cbbf98ab4 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1587,6 +1587,8 @@ svga_poll(void *priv) svga->half_pixel = 0; svga->scrollcache &= 0x07; } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; svga->half_pixel = svga->scrollcache & 0x01; svga->scrollcache = (svga->scrollcache & 0x06) >> 1; } From 06215a0697cae8938427b70a7e69e7c837b4c99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Wed, 10 Sep 2025 00:54:54 +0200 Subject: [PATCH 23/30] Update sdl_joystick.c --- src/qt/sdl_joystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index f1ba0380f..4b2748760 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -50,7 +50,7 @@ joystick_init(void) SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); #endif - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { + if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) { return; } joysticks_present = SDL_NumJoysticks(); From ea7cb1cc55f3b81ea415ec251836b999f00e3c36 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 18:55:59 -0400 Subject: [PATCH 24/30] Some more clang formatting --- src/CMakeLists.txt | 25 +++++- src/floppy/fdd.c | 70 ++++++++-------- src/sound/audio4.c | 194 ++++++++++++++++++++++++-------------------- src/sound/openal.c | 82 +++++++++++-------- src/sound/sndio.c | 182 ++++++++++++++++++++++------------------- src/sound/sound.c | 1 - src/sound/xaudio2.c | 25 +++--- 7 files changed, 321 insertions(+), 258 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 724e1fda6..ec3b2c628 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,8 +103,29 @@ if(INSTRUMENT) add_compile_definitions(USE_INSTRUMENT) endif() -target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom rdisk mo hdd - net print scsi sio snd utils vid voodoo plat ui) +target_link_libraries(86Box + cpu + chipset + mch + dev + mem + fdd + game + cdrom + rdisk + mo + hdd + net + print + scsi + sio + snd + utils + vid + voodoo + plat + ui +) if(HAIKU) target_link_libraries(86Box be) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 8bc946388..bc81c8662 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -105,39 +105,39 @@ static const struct void (*close)(int drive); int size; } loaders[] = { - { "001", img_load, img_close, -1}, - { "002", img_load, img_close, -1}, - { "003", img_load, img_close, -1}, - { "004", img_load, img_close, -1}, - { "005", img_load, img_close, -1}, - { "006", img_load, img_close, -1}, - { "007", img_load, img_close, -1}, - { "008", img_load, img_close, -1}, - { "009", img_load, img_close, -1}, - { "010", img_load, img_close, -1}, - { "12", img_load, img_close, -1}, - { "144", img_load, img_close, -1}, - { "360", img_load, img_close, -1}, - { "720", img_load, img_close, -1}, - { "86F", d86f_load, d86f_close, -1}, - { "BIN", img_load, img_close, -1}, - { "CQ", img_load, img_close, -1}, - { "CQM", img_load, img_close, -1}, - { "DDI", img_load, img_close, -1}, - { "DSK", img_load, img_close, -1}, - { "FDI", fdi_load, fdi_close, -1}, - { "FDF", img_load, img_close, -1}, - { "FLP", img_load, img_close, -1}, - { "HDM", img_load, img_close, -1}, - { "IMA", img_load, img_close, -1}, - { "IMD", imd_load, imd_close, -1}, - { "IMG", img_load, img_close, -1}, - { "JSON", pcjs_load, pcjs_close, -1}, - { "MFM", mfm_load, mfm_close, -1}, - { "TD0", td0_load, td0_close, -1}, - { "VFD", img_load, img_close, -1}, - { "XDF", img_load, img_close, -1}, - { 0, 0, 0, 0 } + { "001", img_load, img_close, -1 }, + { "002", img_load, img_close, -1 }, + { "003", img_load, img_close, -1 }, + { "004", img_load, img_close, -1 }, + { "005", img_load, img_close, -1 }, + { "006", img_load, img_close, -1 }, + { "007", img_load, img_close, -1 }, + { "008", img_load, img_close, -1 }, + { "009", img_load, img_close, -1 }, + { "010", img_load, img_close, -1 }, + { "12", img_load, img_close, -1 }, + { "144", img_load, img_close, -1 }, + { "360", img_load, img_close, -1 }, + { "720", img_load, img_close, -1 }, + { "86F", d86f_load, d86f_close, -1 }, + { "BIN", img_load, img_close, -1 }, + { "CQ", img_load, img_close, -1 }, + { "CQM", img_load, img_close, -1 }, + { "DDI", img_load, img_close, -1 }, + { "DSK", img_load, img_close, -1 }, + { "FDI", fdi_load, fdi_close, -1 }, + { "FDF", img_load, img_close, -1 }, + { "FLP", img_load, img_close, -1 }, + { "HDM", img_load, img_close, -1 }, + { "IMA", img_load, img_close, -1 }, + { "IMD", imd_load, imd_close, -1 }, + { "IMG", img_load, img_close, -1 }, + { "JSON", pcjs_load, pcjs_close, -1 }, + { "MFM", mfm_load, mfm_close, -1 }, + { "TD0", td0_load, td0_close, -1 }, + { "VFD", img_load, img_close, -1 }, + { "XDF", img_load, img_close, -1 }, + { 0, 0, 0, 0 } }; static const struct { @@ -211,7 +211,7 @@ fdd_get_internal_name(int type) int fdd_get_from_internal_name(char *s) { - int c = 0; + int c = 0; while (strlen(drive_types[c].internal_name)) { if (!strcmp((char *) drive_types[c].internal_name, s)) @@ -466,7 +466,7 @@ fdd_load(int drive, char *fn) if (!fn) return; if (strstr(fn, "wp://") == fn) { - offs = 5; + offs = 5; ui_writeprot[drive] = 1; } fn += offs; diff --git a/src/sound/audio4.c b/src/sound/audio4.c index 4e74d2c0c..c76d3253f 100644 --- a/src/sound/audio4.c +++ b/src/sound/audio4.c @@ -34,128 +34,146 @@ #endif #define I_NORMAL 0 -#define I_MUSIC 1 -#define I_WT 2 -#define I_CD 3 -#define I_MIDI 4 +#define I_MUSIC 1 +#define I_WT 2 +#define I_CD 3 +#define I_MIDI 4 -static int audio[5] = {-1, -1, -1, -1, -1}; +static int audio[5] = { -1, -1, -1, -1, -1 }; #ifdef USE_NEW_API static struct audio_swpar info[5]; #else static audio_info_t info[5]; #endif -static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0}; +static int freqs[5] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0 }; -void closeal(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - if(audio[i] != -1){ - close(audio[i]); - } - audio[i] = -1; - } +void +closeal(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + if (audio[i] != -1) + close(audio[i]); + + audio[i] = -1; + } } -void inital(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - audio[i] = open("/dev/audio", O_WRONLY); - if(audio[i] == -1) audio[i] = open("/dev/audio0", O_WRONLY); - if(audio[i] != -1){ +void +inital(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + audio[i] = open("/dev/audio", O_WRONLY); + if (audio[i] == -1) + audio[i] = open("/dev/audio0", O_WRONLY); + if (audio[i] != -1) { #ifdef USE_NEW_API - AUDIO_INITPAR(&info[i]); - ioctl(audio[i], AUDIO_GETPAR, &info[i]); - info[i].sig = 1; - info[i].bits = 16; - info[i].pchan = 2; - info[i].bps = 2; - ioctl(audio[i], AUDIO_SETPAR, &info[i]); + AUDIO_INITPAR(&info[i]); + ioctl(audio[i], AUDIO_GETPAR, &info[i]); + info[i].sig = 1; + info[i].bits = 16; + info[i].pchan = 2; + info[i].bps = 2; + ioctl(audio[i], AUDIO_SETPAR, &info[i]); #else - AUDIO_INITINFO(&info[i]); + AUDIO_INITINFO(&info[i]); #if defined(__NetBSD__) && (__NetBSD_Version__ >= 900000000) - ioctl(audio[i], AUDIO_GETFORMAT, &info[i]); + ioctl(audio[i], AUDIO_GETFORMAT, &info[i]); #else - ioctl(audio[i], AUDIO_GETINFO, &info[i]); + ioctl(audio[i], AUDIO_GETINFO, &info[i]); #endif - info[i].play.channels = 2; - info[i].play.precision = 16; - info[i].play.encoding = AUDIO_ENCODING_SLINEAR; - info[i].hiwat = 5; - info[i].lowat = 3; - ioctl(audio[i], AUDIO_SETINFO, &info[i]); + info[i].play.channels = 2; + info[i].play.precision = 16; + info[i].play.encoding = AUDIO_ENCODING_SLINEAR; + info[i].hiwat = 5; + info[i].lowat = 3; + ioctl(audio[i], AUDIO_SETINFO, &info[i]); #endif - } - } + } + } } -void givealbuffer_common(const void *buf, const uint8_t src, const int size){ - const int freq = freqs[src]; - int16_t* output; - int output_size; - int16_t* conv; - int conv_size; - int i; - double gain; - int target_rate; - if(audio[src] == -1) return; +void +givealbuffer_common(const void *buf, const uint8_t src, const int size) +{ + const int freq = freqs[src]; + int16_t* output; + int output_size; + int16_t* conv; + int conv_size; + double gain; + int target_rate; - gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + if(audio[src] == -1) + return; - if(sound_is_float){ - float* input = (float*)buf; - conv_size = sizeof(int16_t) * size; - conv = malloc(conv_size); - for(i = 0; i < conv_size / sizeof(int16_t); i++){ - conv[i] = 32767 * input[i]; - } - }else{ - conv_size = size * sizeof(int16_t); - conv = malloc(conv_size); - memcpy(conv, buf, conv_size); - } + gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + + if (sound_is_float) { + float* input = (float*)buf; + conv_size = sizeof(int16_t) * size; + conv = malloc(conv_size); + for (int i = 0; i < conv_size / sizeof(int16_t); i++) + conv[i] = 32767 * input[i]; + } else { + conv_size = size * sizeof(int16_t); + conv = malloc(conv_size); + memcpy(conv, buf, conv_size); + } #ifdef USE_NEW_API - target_rate = info[src].rate; + target_rate = info[src].rate; #else - target_rate = info[src].play.sample_rate; + target_rate = info[src].play.sample_rate; #endif - output_size = (double)conv_size * target_rate / freq; - output_size -= output_size % 4; - output = malloc(output_size); - - for(i = 0; i < output_size / sizeof(int16_t) / 2; i++){ - int ind = i * freq / target_rate * 2; - output[i * 2 + 0] = conv[ind + 0] * gain; - output[i * 2 + 1] = conv[ind + 1] * gain; - } + output_size = (double) conv_size * target_rate / freq; + output_size -= output_size % 4; + output = malloc(output_size); + + for (int i = 0; i < output_size / sizeof(int16_t) / 2; i++) { + int ind = i * freq / target_rate * 2; + output[i * 2 + 0] = conv[ind + 0] * gain; + output[i * 2 + 1] = conv[ind + 1] * gain; + } - write(audio[src], output, output_size); + write(audio[src], output, output_size); - free(conv); - free(output); + free(conv); + free(output); } -void givealbuffer(const void *buf){ - givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); +void +givealbuffer(const void *buf) +{ + givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); } -void givealbuffer_music(const void *buf){ - givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); +void +givealbuffer_music(const void *buf) +{ + givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); } -void givealbuffer_wt(const void *buf){ - givealbuffer_common(buf, I_WT, WTBUFLEN << 1); +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, I_WT, WTBUFLEN << 1); } -void givealbuffer_cd(const void *buf){ - givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); +void +givealbuffer_cd(const void *buf) +{ + givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); } -void givealbuffer_midi(const void *buf, const uint32_t size){ - givealbuffer_common(buf, I_MIDI, (int) size); + +void +givealbuffer_midi(const void *buf, const uint32_t size) +{ + givealbuffer_common(buf, I_MIDI, (int) size); } - -void al_set_midi(const int freq, UNUSED(const int buf_size)){ - freqs[I_MIDI] = freq; + +void +al_set_midi(const int freq, UNUSED(const int buf_size)) +{ + freqs[I_MIDI] = freq; } diff --git a/src/sound/openal.c b/src/sound/openal.c index 90f626362..c2addb270 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -37,6 +37,12 @@ #define FREQ SOUND_FREQ #define BUFLEN SOUNDBUFLEN +#define I_NORMAL 0 +#define I_MUSIC 1 +#define I_WT 2 +#define I_CD 3 +#define I_MIDI 4 + ALuint buffers[4]; /* front and back buffers */ ALuint buffers_music[4]; /* front and back buffers */ ALuint buffers_wt[4]; /* front and back buffers */ @@ -124,7 +130,7 @@ inital(void) int16_t *cd_buf_int16 = NULL; int16_t *midi_buf_int16 = NULL; - int init_midi = 0; + int init_midi = 0; if (initialized) return; @@ -166,32 +172,36 @@ inital(void) else alGenSources(4, source); - alSource3f(source[0], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[0], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[0], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[0], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[1], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[1], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[1], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[2], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[2], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[2], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[3], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[3], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[3], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[I_NORMAL], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_NORMAL], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_NORMAL], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_NORMAL], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_NORMAL], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_MUSIC], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MUSIC], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MUSIC], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_MUSIC], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_MUSIC], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_WT], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_WT], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_WT], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_WT], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_WT], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_CD], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_CD], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_CD], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_CD], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_CD], AL_SOURCE_RELATIVE, AL_TRUE); + if (init_midi) { - alSource3f(source[4], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[4], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[4], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[4], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[4], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[I_MIDI], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MIDI], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MIDI], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_MIDI], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_MIDI], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { @@ -228,18 +238,18 @@ inital(void) } } - alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_music); - alSourceQueueBuffers(source[2], 4, buffers_wt); - alSourceQueueBuffers(source[3], 4, buffers_cd); + alSourceQueueBuffers(source[I_NORMAL], 4, buffers); + alSourceQueueBuffers(source[I_MUSIC], 4, buffers_music); + alSourceQueueBuffers(source[I_WT], 4, buffers_wt); + alSourceQueueBuffers(source[I_CD], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[4], 4, buffers_midi); - alSourcePlay(source[0]); - alSourcePlay(source[1]); - alSourcePlay(source[2]); - alSourcePlay(source[3]); + alSourceQueueBuffers(source[I_MIDI], 4, buffers_midi); + alSourcePlay(source[I_NORMAL]); + alSourcePlay(source[I_MUSIC]); + alSourcePlay(source[I_WT]); + alSourcePlay(source[I_CD]); if (init_midi) - alSourcePlay(source[4]); + alSourcePlay(source[I_MIDI]); if (sound_is_float) { if (init_midi) diff --git a/src/sound/sndio.c b/src/sound/sndio.c index 2fe1434df..7459dc130 100644 --- a/src/sound/sndio.c +++ b/src/sound/sndio.c @@ -32,109 +32,125 @@ #define I_CD 3 #define I_MIDI 4 -static struct sio_hdl* audio[5] = {NULL, NULL, NULL, NULL, NULL}; +static struct sio_hdl* audio[5] = { NULL, NULL, NULL, NULL, NULL }; static struct sio_par info[5]; -static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0}; +static int freqs[5] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0 }; -void closeal(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - if(audio[i] != NULL){ - sio_close(audio[i]); - } - audio[i] = NULL; - } +void +closeal(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + if (audio[i] != NULL) + sio_close(audio[i]); + + audio[i] = NULL; + } } -void inital(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - audio[i] = sio_open(SIO_DEVANY, SIO_PLAY, 0); - if(audio[i] != NULL){ - int rate; - int max_frames; - sio_getpar(audio[i], &info[i]); - rate = info[i].rate; - max_frames = info[i].bufsz; - sio_initpar(&info[i]); - info[i].sig = 1; - info[i].bits = 16; - info[i].pchan = 2; - info[i].rate = rate; - info[i].appbufsz = max_frames; - sio_setpar(audio[i], &info[i]); - sio_getpar(audio[i], &info[i]); - if(!sio_start(audio[i])){ - sio_close(audio[i]); - audio[i] = NULL; - } - } - } +void +inital(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + audio[i] = sio_open(SIO_DEVANY, SIO_PLAY, 0); + if (audio[i] != NULL) { + int rate; + int max_frames; + sio_getpar(audio[i], &info[i]); + rate = info[i].rate; + max_frames = info[i].bufsz; + sio_initpar(&info[i]); + info[i].sig = 1; + info[i].bits = 16; + info[i].pchan = 2; + info[i].rate = rate; + info[i].appbufsz = max_frames; + sio_setpar(audio[i], &info[i]); + sio_getpar(audio[i], &info[i]); + if (!sio_start(audio[i])) { + sio_close(audio[i]); + audio[i] = NULL; + } + } + } } -void givealbuffer_common(const void *buf, const uint8_t src, const int size){ - const int freq = freqs[src]; - int16_t* output; - int output_size; - int16_t* conv; - int conv_size; - int i; - double gain; - int target_rate; - if(audio[src] == NULL) return; +void +givealbuffer_common(const void *buf, const uint8_t src, const int size) +{ + const int freq = freqs[src]; + int16_t* output; + int output_size; + int16_t* conv; + int conv_size; + double gain; + int target_rate; + if (audio[src] == NULL) + return; - gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); - if(sound_is_float){ - float* input = (float*)buf; - conv_size = sizeof(int16_t) * size; - conv = malloc(conv_size); - for(i = 0; i < conv_size / sizeof(int16_t); i++){ - conv[i] = 32767 * input[i]; - } - }else{ - conv_size = size * sizeof(int16_t); - conv = malloc(conv_size); - memcpy(conv, buf, conv_size); - } + if (sound_is_float) { + float* input = (float*) buf; + conv_size = sizeof(int16_t) * size; + conv = malloc(conv_size); + for (int i = 0; i < conv_size / sizeof(int16_t); i++) + conv[i] = 32767 * input[i]; + } else { + conv_size = size * sizeof(int16_t); + conv = malloc(conv_size); + memcpy(conv, buf, conv_size); + } - target_rate = info[src].rate; + target_rate = info[src].rate; - output_size = (double)conv_size * target_rate / freq; - output_size -= output_size % 4; - output = malloc(output_size); - - for(i = 0; i < output_size / sizeof(int16_t) / 2; i++){ - int ind = i * freq / target_rate * 2; - output[i * 2 + 0] = conv[ind + 0] * gain; - output[i * 2 + 1] = conv[ind + 1] * gain; - } + output_size = (double) conv_size * target_rate / freq; + output_size -= output_size % 4; + output = malloc(output_size); + + for (int i = 0; i < output_size / sizeof(int16_t) / 2; i++) { + int ind = i * freq / target_rate * 2; + output[i * 2 + 0] = conv[ind + 0] * gain; + output[i * 2 + 1] = conv[ind + 1] * gain; + } - sio_write(audio[src], output, output_size); + sio_write(audio[src], output, output_size); - free(conv); - free(output); + free(conv); + free(output); } -void givealbuffer(const void *buf){ - givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); +void +givealbuffer(const void *buf) +{ + givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); } -void givealbuffer_music(const void *buf){ - givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); +void +givealbuffer_music(const void *buf) +{ + givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); } -void givealbuffer_wt(const void *buf){ - givealbuffer_common(buf, I_WT, WTBUFLEN << 1); +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, I_WT, WTBUFLEN << 1); } -void givealbuffer_cd(const void *buf){ - givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); +void +givealbuffer_cd(const void *buf) +{ + givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); } -void givealbuffer_midi(const void *buf, const uint32_t size){ - givealbuffer_common(buf, I_MIDI, (int) size); + +void +givealbuffer_midi(const void *buf, const uint32_t size) +{ + givealbuffer_common(buf, I_MIDI, (int) size); } - -void al_set_midi(const int freq, UNUSED(const int buf_size)){ - freqs[I_MIDI] = freq; + +void +al_set_midi(const int freq, UNUSED(const int buf_size)) +{ + freqs[I_MIDI] = freq; } diff --git a/src/sound/sound.c b/src/sound/sound.c index c81dc47b0..579056359 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -55,7 +55,6 @@ int wavetable_pos_global = 0; int sound_gain = 0; static sound_handler_t sound_handlers[8]; - static sound_handler_t music_handlers[8]; static sound_handler_t wavetable_handlers[8]; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 2aee97efc..b526fa72f 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -39,8 +39,8 @@ static void *xaudio2_handle = NULL; static HRESULT(WINAPI *pXAudio2Create)(IXAudio2 **ppXAudio2, uint32_t Flags, XAUDIO2_PROCESSOR XAudio2Processor); static dllimp_t xaudio2_imports[] = { - {"XAudio2Create", &pXAudio2Create}, - { NULL, NULL }, + {"XAudio2Create", &pXAudio2Create }, + { NULL, NULL }, }; # define XAudio2Create pXAudio2Create #endif @@ -119,22 +119,18 @@ void inital(void) { #if defined(_WIN32) && !defined(USE_FAUDIO) - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) xaudio2_handle = dynld_module("xaudio2_9.dll", xaudio2_imports); - } - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) xaudio2_handle = dynld_module("xaudio2_9redist.dll", xaudio2_imports); - } - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) return; - } #endif - if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) { + if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) return; - } if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0)) { IXAudio2_Release(xaudio2); @@ -209,6 +205,7 @@ closeal(void) { if (!initialized) return; + initialized = 0; (void) IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); @@ -229,9 +226,11 @@ closeal(void) IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); - srcvoice = srcvoicecd = srcvoicemidi = NULL; - mastervoice = NULL; - xaudio2 = NULL; + srcvoice = NULL; + srcvoicecd = NULL; + srcvoicemidi = NULL; + mastervoice = NULL; + xaudio2 = NULL; #if defined(_WIN32) && !defined(USE_FAUDIO) dynld_close(xaudio2_handle); From 1e0f92185f11e3030018c27d415075e8b8f35f05 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:18:14 -0400 Subject: [PATCH 25/30] Sensible defaults in cartridge.c --- src/device/cartridge.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device/cartridge.c b/src/device/cartridge.c index 00464026a..cb3c5e412 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -92,8 +92,8 @@ cart_image_close(int drive) static void cart_image_load(int drive, char *fn) { - FILE *fp; - uint32_t size; + FILE *fp = NULL; + uint32_t size = 0; uint32_t base = 0x00000000; cart_image_close(drive); @@ -137,7 +137,7 @@ cart_image_load(int drive, char *fn) static void cart_load_common(int drive, char *fn, uint8_t hard_reset) { - FILE *fp; + FILE *fp = NULL; cartridge_log("Cartridge: loading drive %d with '%s'\n", drive, fn); From 6f9930417dcc2e09900c200ada1e6d5f0602f069 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:35:15 -0400 Subject: [PATCH 26/30] A few EMU8000 Cleanups --- src/include/86box/snd_emu8k.h | 10 +++++---- src/sound/snd_emu8k.c | 39 +++++++++++++++++------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index 4bad23b97..fcbad4cfa 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -199,8 +199,8 @@ typedef struct emu8k_voice_t { * something, similarly to targets and current, but... of what? * what is curious is that if they are already zero, they are not written to, so it really * looks like they are information about the status of the channel. (lfo position maybe?) */ - uint32_t unknown_data0_4; - uint32_t unknown_data0_5; + uint32_t z2; + uint32_t z1; union { uint32_t psst; struct { @@ -229,7 +229,7 @@ typedef struct emu8k_voice_t { }; #define CCCA_FILTQ_GET(ccca) (ccca >> 28) #define CCCA_FILTQ_SET(ccca, q) ccca = (ccca & 0x0FFFFFFF) | (q << 28) -/* Bit 27 should always be zero */ +/* Bit 27 should always be zero on EMU8000 */ #define CCCA_DMA_ACTIVE(ccca) (ccca & 0x04000000) #define CCCA_DMA_WRITE_MODE(ccca) (ccca & 0x02000000) #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca & 0x01000000) @@ -316,7 +316,9 @@ typedef struct emu8k_voice_t { int env_engine_on; - emu8k_mem_internal_t addr, loop_start, loop_end; + emu8k_mem_internal_t addr; + emu8k_mem_internal_t loop_start; + emu8k_mem_internal_t loop_end; int32_t initial_att; int32_t initial_filter; diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 822abeeaa..c3efdaaff 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -556,11 +556,11 @@ emu8k_inw(uint16_t addr, void *priv) return ret; case 4: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); + READ16(addr, emu8k->voice[emu8k->cur_voice].z2); return ret; case 5: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); + READ16(addr, emu8k->voice[emu8k->cur_voice].z1); return ret; case 6: @@ -888,11 +888,11 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) return; case 4: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); + WRITE16(addr, emu8k->voice[emu8k->cur_voice].z2, val); return; case 5: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); + WRITE16(addr, emu8k->voice[emu8k->cur_voice].z1, val); return; case 6: @@ -1006,7 +1006,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val & 0xF) / 15.0; break; - case 0xB: + case 0xB: #if 0 emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; #endif @@ -1050,7 +1050,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) case 1: emu8k->reverb_engine.refl_in_amp = val & 0xFF; break; - case 3: + case 3: #if 0 emu8k->reverb_engine.refl_in_amp_r = val&0xFF; #endif @@ -1811,11 +1811,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #elif defined FILTER_MOOG @@ -1823,15 +1822,15 @@ emu8k_update(emu8k_t *emu8k) dat <<= 8; dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ - int64_t t1 = emu_voice->filt_buffer[1]; + int64_t t1 = emu_voice->filt_buffer[1]; emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - int64_t t2 = emu_voice->filt_buffer[2]; + int64_t t2 = emu_voice->filt_buffer[2]; emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); - int64_t t3 = emu_voice->filt_buffer[3]; + int64_t t3 = emu_voice->filt_buffer[3]; emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); @@ -1841,11 +1840,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[0] = ClipBuffer(dat); dat = (int32_t) (emu_voice->filt_buffer[4] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #elif defined FILTER_CONSTANT @@ -1864,11 +1862,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #endif } @@ -2372,6 +2369,8 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) void emu8k_close(emu8k_t *emu8k) { - free(emu8k->rom); - free(emu8k->ram); + if (emu8k->rom) + free(emu8k->rom); + if (emu8k->ram) + free(emu8k->ram); } From af007b12e75f754f994fe1a200145419306d435c Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:37:41 -0400 Subject: [PATCH 27/30] path_get_basename helper function --- src/include/86box/path.h | 3 ++- src/qt/qt_platform.cpp | 7 +++++++ src/unix/unix.c | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/include/86box/path.h b/src/include/86box/path.h index f1c5e4177..ef66c0a30 100644 --- a/src/include/86box/path.h +++ b/src/include/86box/path.h @@ -1,3 +1,4 @@ +extern char *path_get_basename(const char *path); extern void path_get_dirname(char *dest, const char *path); extern char *path_get_filename(char *s); extern char *path_get_extension(char *s); @@ -5,4 +6,4 @@ extern void path_append_filename(char *dest, const char *s1, const char *s2); extern void path_slash(char *path); extern const char *path_get_slash(char *path); extern void path_normalize(char *path); -extern int path_abs(char *path); \ No newline at end of file +extern int path_abs(char *path); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 03bc68390..240315faa 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -267,6 +267,13 @@ plat_getcwd(char *bufp, int max) return 0; } +char * +path_get_basename(const char *path) +{ + QFileInfo fi(path); + return fi.fileName().toUtf8().data(); +} + void path_get_dirname(char *dest, const char *path) { diff --git a/src/unix/unix.c b/src/unix/unix.c index de35f4e93..4f3990590 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -351,7 +351,7 @@ plat_put_backslash(char *s) /* Return the last element of a pathname. */ char * -plat_get_basename(const char *path) +path_get_basename(const char *path) { int c = (int) strlen(path); @@ -1420,6 +1420,7 @@ main(int argc, char **argv) f_rl_callback_handler_remove(); return 0; } + char * plat_vidapi_name(UNUSED(int i)) { From f937b8124627a4b32795cdaf4e18d24c9e976307 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:49:39 -0400 Subject: [PATCH 28/30] PCjr Cleanups --- src/machine/m_pcjr.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index b7d840224..9dba8795f 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -774,14 +774,14 @@ pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv)) static const device_config_t pcjr_config[] = { // clang-format off { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = PCJR_RGB, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = PCJR_RGB, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "RGB", .value = PCJR_RGB }, { .description = "Composite", .value = PCJR_COMPOSITE }, { .description = "RGB (no brown)", .value = PCJR_RGB_NO_BROWN }, @@ -807,11 +807,11 @@ static const device_config_t pcjr_config[] = { .bios = { { 0 } } }, { - .name = "apply_hd", - .description = "Apply overscan deltas", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "apply_hd", + .description = "Apply overscan deltas", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on From cb5a12e2a09ccf5d9c43c8e3d79aae5ce57568e6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:59:42 -0400 Subject: [PATCH 29/30] Improve the macos joystick fix --- src/qt/sdl_joystick.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index 4b2748760..fddb730e7 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -50,9 +50,13 @@ joystick_init(void) SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); #endif - if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) { +#ifdef __APPLE__ + if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) +#else + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) +#endif return; - } + joysticks_present = SDL_NumJoysticks(); memset(sdl_joy, 0, sizeof(sdl_joy)); From b3cf1db56863a8e90debd68f1ce360769335fb05 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:49:05 +0800 Subject: [PATCH 30/30] Add NEC PowerMate V2xxx/P2xxx! Let's Add NEC PowerMate V2xxx/P2xxx! It was based on Intel CU430HX (Cumberland). --- src/machine/m_at_socket7.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index b0651a8af..6101513cd 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -155,6 +155,10 @@ static const device_config_t cu430hx_config[] = { .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1003DK08.BIO", "roms/machines/cu430hx/1003DK08.BI1", "roms/machines/cu430hx/1003DK08.BI2", "roms/machines/cu430hx/1003DK08.BI3", "roms/machines/cu430hx/1003DK08.RCV", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.04.DK0K (NEC PowerMate V2xxx/P2xxx)", .internal_name = "powermatev2p2", .bios_type = BIOS_NORMAL, + .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1004DK0K.BIO", "roms/machines/cu430hx/1004DK0K.BI1", + "roms/machines/cu430hx/1004DK0K.BI2", "roms/machines/cu430hx/1004DK0K.BI3", + "roms/machines/cu430hx/1004DK0K.RCV", "" } }, { .name = "Intel AMIBIOS - Revision 1.00.06.DK0", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3",