From 06bacb6912be8688cb3f617a4e4edb02195ae3f0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 7 Apr 2025 01:01:26 +0600 Subject: [PATCH 01/12] Bochs SVGA: Buffer window switching now works properly --- src/video/vid_bochs_vbe.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index ac7bc00cb..6dc015fb0 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -338,20 +338,13 @@ bochs_vbe_recalctimings(svga_t* svga) svga->rowoffset = (dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] / 2) >> 3; svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] >> 3); + + svga->fullchange = 3; } else { svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)); svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + - (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); - } - if (svga->ma_latch != dev->ma_latch_old) { - if (svga->bpp == 4) { - svga->maback = (svga->maback - (dev->ma_latch_old << 2)) + - (svga->ma_latch << 2); - } else { - svga->maback = (svga->maback - (dev->ma_latch_old)) + - (svga->ma_latch); - dev->ma_latch_old = svga->ma_latch; - } + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); + svga->fullchange = 3; } if (svga->bpp == 4) @@ -482,18 +475,10 @@ bochs_vbe_outw(const uint16_t addr, const uint16_t val, void *priv) } else { svga->rowoffset = dev->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8)); svga->ma_latch = (dev->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] * svga->rowoffset) + - (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); - } - if (svga->ma_latch != dev->ma_latch_old) { - if (svga->bpp == 4) { - svga->maback = (svga->maback - (dev->ma_latch_old << 2)) + - (svga->ma_latch << 2); - } else { - svga->maback = (svga->maback - (dev->ma_latch_old)) + - (svga->ma_latch); - dev->ma_latch_old = svga->ma_latch; - } + (dev->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] * ((svga->bpp == 15) ? 2 : (svga->bpp / 8))); } + + svga->fullchange = 3; } else svga_recalctimings(&dev->svga); From 449c224ff7dd4640088321c3befa65c4a13ab5f7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 6 Apr 2025 21:23:53 +0200 Subject: [PATCH 02/12] SiS 471: Fix array out of bounds writes. --- src/chipset/sis_85c4xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/sis_85c4xx.c b/src/chipset/sis_85c4xx.c index 6e26a4751..537675a85 100644 --- a/src/chipset/sis_85c4xx.c +++ b/src/chipset/sis_85c4xx.c @@ -375,7 +375,7 @@ sis_85c4xx_init(const device_t *info) dev->reg_base = info->local & 0xff; if (dev->is_471) { - dev->reg_last = dev->reg_base + 0x76; + dev->reg_last = 0x76; dev->smram = smram_add(); From e48d64de4572e8a42217f51e2c69327f0d1fec64 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 01:44:12 +0200 Subject: [PATCH 03/12] SCSI CD-ROM/Disk/MO/ZIP: Treat data commands with request length 0 in ATAPI PIO mode as non-data commands, also allow WIN_SRST to go through BSY, fixes the regressions introduced in build 6731 reported by JVERNET. --- src/disk/hdc_ide.c | 51 +++++++++++++++++++++++++++++++------------ src/disk/mo.c | 5 ++++- src/disk/zip.c | 5 ++++- src/scsi/scsi_cdrom.c | 20 ++++++++++++----- src/scsi/scsi_disk.c | 5 ++++- 5 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 01690cd70..04e580e72 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1208,7 +1208,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) ide->tf->atastat = BSY_STAT; if (ide->tf->pos >= dev->packet_len) { - ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read"); + // ide_log("%i bytes %s, command done\n", ide->tf->pos, out ? "written" : "read"); + ide_log("%i bytes %s, command done, %i sectors left\n", ide->tf->pos, out ? "written" : "read", + dev->sector_len); ide->tf->pos = dev->request_pos = 0; @@ -1262,13 +1264,12 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) ide_atapi_callback(ide); ide_set_callback(ide, 0.0); } else { - ide->sc->packet_status = PHASE_COMPLETE; - ide->sc->callback = 0.0; - if (ide->phase_data_out != NULL) (void) ide->phase_data_out(dev); - ide_atapi_callback(ide); + if ((ide->sc->packet_status == PHASE_COMPLETE) && + (ide->sc->callback == 0.0)) + ide_atapi_callback(ide); } } } else { @@ -1280,10 +1281,9 @@ ide_atapi_pio_request(ide_t *ide, uint8_t out) if (ide->command_stop != NULL) ide->command_stop(dev); - ide->sc->packet_status = PHASE_COMPLETE; - ide->sc->callback = 0.0; - - ide_atapi_callback(ide); + if ((ide->sc->packet_status == PHASE_COMPLETE) && + (ide->sc->callback == 0.0)) + ide_atapi_callback(ide); } } else if (ide->read != NULL) ide->read(dev); @@ -1299,8 +1299,8 @@ ide_atapi_packet_read(ide_t *ide) uint16_t ret = 0; if (dev && dev->temp_buffer && (dev->packet_status == PHASE_DATA_IN)) { - ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", - dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len); + /* ide_log("PHASE_DATA_IN read: %i, %i, %i, %i\n", + dev->request_pos, dev->max_transfer_len, ide->tf->pos, dev->packet_len); */ bufferw = (uint16_t *) dev->temp_buffer; @@ -1722,7 +1722,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) break; case 0x7: /* Command register */ - if (ide->tf->atastat & (BSY_STAT | DRQ_STAT)) + if ((ide->tf->atastat & (BSY_STAT | DRQ_STAT)) && + ((val != WIN_SRST) || (ide->type != IDE_ATAPI))) break; if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS))) @@ -2158,7 +2159,8 @@ ide_read_alt_status(UNUSED(const uint16_t addr), void *priv) if (!(addr & 0x0001)) ret = ide_status(ide, ide_drives[ch ^ 1], ch); - ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + // ide_log("[%04X:%08X] ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); + // ide_log("ide_read_alt_status(%04X, %08X) = %02X\n", CS, cpu_state.pc, addr, priv, ret); return ret; } @@ -3159,6 +3161,13 @@ ide_init(const device_t *info) ide_board_init(1, HDC_SECONDARY_IRQ, HDC_SECONDARY_BASE, HDC_SECONDARY_SIDE, info->local, info->flags); break; + case 8 ... 0x0d: + ide_board_init(2, -1, 0, 0, info->local, info->flags); + + if (info->local & 1) + ide_board_init(3, -1, 0, 0, info->local, info->flags); + break; + default: break; } @@ -3540,7 +3549,7 @@ const device_t mcide_device = { .name = "MCA McIDE Controller", .internal_name = "ide_mcide", .flags = DEVICE_MCA, - .local = 3, + .local = 1, .init = mcide_init, .close = mcide_close, .reset = mcide_reset, @@ -3661,3 +3670,17 @@ const device_t ide_qua_pnp_device = { .force_redraw = NULL, .config = NULL }; + +const device_t ide_pci_ter_qua_2ch_device = { + .name = "PCI IDE Controller (Dual-Channel Tertiary/Quaternary)", + .internal_name = "ide_pci_ter_qua_2ch", + .flags = DEVICE_PCI, + .local = 0x0d, + .init = ide_init, + .close = ide_close, + .reset = ide_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/disk/mo.c b/src/disk/mo.c index f1cd3b983..a20333404 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -584,7 +584,10 @@ mo_data_command_finish(mo_t *dev, int len, const int block_len, mo_command_write_dma(dev); } else { mo_update_request_length(dev, len, block_len); - if (direction == 0) + if ((dev->drv->bus_type != MO_BUS_SCSI) && + (dev->tf->request_length == 0)) + mo_command_complete(dev); + else if (direction == 0) mo_command_read(dev); else mo_command_write(dev); diff --git a/src/disk/zip.c b/src/disk/zip.c index eecafb802..7a407c5fe 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -665,7 +665,10 @@ zip_data_command_finish(zip_t *dev, int len, const int block_len, zip_command_write_dma(dev); } else { zip_update_request_length(dev, len, block_len); - if (direction == 0) + if ((dev->drv->bus_type != ZIP_BUS_SCSI) && + (dev->tf->request_length == 0)) + zip_command_complete(dev); + else if (direction == 0) zip_command_read(dev); else zip_command_write(dev); diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index e5689dd76..2b37eeaca 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -15,6 +15,7 @@ */ #include #include +#define ENABLE_SCSI_CDROM_LOG 2 #ifdef ENABLE_SCSI_CDROM_LOG #include #endif @@ -689,6 +690,7 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) bytes_per_second *= (double) dev->drv->cur_speed; } else { bytes_per_second = scsi_cdrom_bus_speed(dev); + pclog("%lf bytes per second\n", bytes_per_second); if (bytes_per_second == 0.0) { dev->callback = -1; /* Speed depends on SCSI controller */ return; @@ -698,19 +700,24 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) period = 1000000.0 / bytes_per_second; scsi_cdrom_log(dev->log, "Byte transfer period: %" PRIu64 " us\n", (uint64_t) period); + pclog("Byte transfer period: %lf us (%i bytes)\n", period, dev->packet_len); if (dev->was_cached == -1) period *= (double) dev->packet_len; else { + int atapi_num = (dev->tf->request_length < dev->block_len) ? + dev->block_len : dev->tf->request_length; + atapi_num = (atapi_num / dev->block_len) * dev->block_len; + if (atapi_num > dev->sector_len) + atapi_num = dev->sector_len; const int num = ((dev->drv->bus_type == CDROM_BUS_SCSI) || - (dev->block_len == 0)) ? - dev->requested_blocks : - ((scsi_cdrom_current_mode(dev) == 2) ? 1 : - (dev->packet_len / dev->block_len)); + (dev->block_len == 0)) ? dev->requested_blocks : + ((scsi_cdrom_current_mode(dev) == 2) ? 1 : atapi_num); period *= ((double) num) * 2352.0; } scsi_cdrom_log(dev->log, "Sector transfer period: %" PRIu64 " us\n", (uint64_t) period); + pclog("Data transfer period: %lf us\n", period); dev->callback += period; } scsi_cdrom_set_callback(dev); @@ -800,7 +807,10 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al scsi_cdrom_command_write_dma(dev); } else { scsi_cdrom_update_request_length(dev, len, block_len); - if (direction == 0) + if ((dev->drv->bus_type != CDROM_BUS_SCSI) && + (dev->tf->request_length == 0)) + scsi_cdrom_command_complete(dev); + else if (direction == 0) scsi_cdrom_command_read(dev); else scsi_cdrom_command_write(dev); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 8528db1fb..0a035a23d 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -570,7 +570,10 @@ scsi_disk_data_command_finish(scsi_disk_t *dev, int len, const int block_len, scsi_disk_command_write_dma(dev); } else { scsi_disk_update_request_length(dev, len, block_len); - if (direction == 0) + if ((dev->drv->bus_type != HDD_BUS_SCSI) && + (dev->tf->request_length == 0)) + scsi_disk_command_complete(dev); + else if (direction == 0) scsi_disk_command_read(dev); else scsi_disk_command_write(dev); From b93af353efc0f9a93690d4011ad0e4b456ae7412 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 01:46:09 +0200 Subject: [PATCH 04/12] SCSI CD-ROM: Remove leftover excess logging. --- src/scsi/scsi_cdrom.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 2b37eeaca..306eed884 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -15,7 +15,6 @@ */ #include #include -#define ENABLE_SCSI_CDROM_LOG 2 #ifdef ENABLE_SCSI_CDROM_LOG #include #endif @@ -681,8 +680,7 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) /* Seek time is in us. */ period = cdrom_seek_time(dev->drv); - scsi_cdrom_log(dev->log, "Seek period: %" PRIu64 " us\n", - (uint64_t) period); + scsi_cdrom_log(dev->log, "Seek period: %lf us\n", period); dev->callback += period; /* 44100 * 16 bits * 2 channels = 176400 bytes per second */ @@ -690,7 +688,6 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) bytes_per_second *= (double) dev->drv->cur_speed; } else { bytes_per_second = scsi_cdrom_bus_speed(dev); - pclog("%lf bytes per second\n", bytes_per_second); if (bytes_per_second == 0.0) { dev->callback = -1; /* Speed depends on SCSI controller */ return; @@ -698,9 +695,7 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) } period = 1000000.0 / bytes_per_second; - scsi_cdrom_log(dev->log, "Byte transfer period: %" PRIu64 " us\n", - (uint64_t) period); - pclog("Byte transfer period: %lf us (%i bytes)\n", period, dev->packet_len); + scsi_cdrom_log(dev->log, "Byte transfer period: %lf us\n", period); if (dev->was_cached == -1) period *= (double) dev->packet_len; else { @@ -715,9 +710,7 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) period *= ((double) num) * 2352.0; } - scsi_cdrom_log(dev->log, "Sector transfer period: %" PRIu64 " us\n", - (uint64_t) period); - pclog("Data transfer period: %lf us\n", period); + scsi_cdrom_log(dev->log, "Sector transfer period: %lf us\n", period); dev->callback += period; } scsi_cdrom_set_callback(dev); From 018ff46253293e39dc6c7aa9140c3425b6609825 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 05:42:41 +0200 Subject: [PATCH 05/12] CD-ROM: Actually remember and use the correct number of sectors for the period, fixes... well, any kind of data reading. --- src/include/86box/scsi_cdrom.h | 1 + src/scsi/scsi_cdrom.c | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index 7bb39d9db..c01f347a8 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -70,6 +70,7 @@ typedef struct scsi_cdrom_t { int was_cached; int toc_cached; int media_access; + int sectors_num; uint8_t vendor_type; uint8_t ven_cmd_is_data[256]; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 306eed884..246f185e8 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -699,14 +699,9 @@ scsi_cdrom_set_period(scsi_cdrom_t *dev) if (dev->was_cached == -1) period *= (double) dev->packet_len; else { - int atapi_num = (dev->tf->request_length < dev->block_len) ? - dev->block_len : dev->tf->request_length; - atapi_num = (atapi_num / dev->block_len) * dev->block_len; - if (atapi_num > dev->sector_len) - atapi_num = dev->sector_len; const int num = ((dev->drv->bus_type == CDROM_BUS_SCSI) || - (dev->block_len == 0)) ? dev->requested_blocks : - ((scsi_cdrom_current_mode(dev) == 2) ? 1 : atapi_num); + (dev->block_len == 0)) ? dev->sectors_num : + ((scsi_cdrom_current_mode(dev) == 2) ? 1 : dev->sectors_num); period *= ((double) num) * 2352.0; } @@ -1051,6 +1046,8 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, const int msf, const int type, const int int num = (dev->drv->bus_type == CDROM_BUS_SCSI) ? dev->requested_blocks : 1; + dev->sectors_num = 0; + if (dev->drv->cd_status == CD_STATUS_EMPTY) scsi_cdrom_not_ready(dev); else if (dev->sector_pos > dev->drv->cdrom_capacity) { @@ -1085,6 +1082,7 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, const int msf, const int type, const int dev->drv->seek_pos = dev->sector_pos; dev->sector_len--; + dev->sectors_num++; dev->buffer_pos += temp_len; } @@ -2423,6 +2421,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) int32_t *BufLen; dev->was_cached = -1; + dev->sectors_num = 1; if (dev->drv->bus_type == CDROM_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; From 3b5966eb465830b4fdb367d89cd44a930cb098ea Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 06:03:19 +0200 Subject: [PATCH 06/12] LDS/LES/LFS/LGS/LSS: Fix segment wraparounds in 16-bit address mode. --- src/codegen/codegen_ops_x86-64.h | 7 ++++ src/codegen/codegen_ops_x86.h | 7 ++++ src/codegen_new/codegen_backend_arm64_uops.c | 2 + src/codegen_new/codegen_backend_arm_uops.c | 2 + src/codegen_new/codegen_backend_x86-64_uops.c | 9 +++- src/codegen_new/codegen_backend_x86_uops.c | 9 +++- src/codegen_new/codegen_ir_defs.h | 10 ++++- src/codegen_new/codegen_ops_misc.c | 8 ++-- src/codegen_new/codegen_reg.c | 2 + src/codegen_new/codegen_reg.h | 4 +- src/cpu/386_common.h | 26 ++++++++++++ src/cpu/cpu.h | 5 ++- src/cpu/x86_ops_mov_seg.h | 41 +++++++++++-------- src/cpu/x86_ops_ret.h | 2 +- src/cpu/x86_ops_ret_2386.h | 2 +- 15 files changed, 105 insertions(+), 31 deletions(-) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index e46f55a05..1be5dfdce 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -1054,6 +1054,13 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); + if (!(op_32 & 0x200)) { + addbyte(0x25) /* AND EAX, ffffh */ + addbyte(0xff); + addbyte(0xff); + addbyte(0x00); + addbyte(0x00); + } MEM_LOAD_ADDR_EA_W(seg); } static __inline void diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index c48324c2a..7a56b5fe1 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -802,6 +802,13 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); + if (!(op_32 & 0x200)) { + addbyte(0x25) /* AND EAX, ffffh */ + addbyte(0xff); + addbyte(0xff); + addbyte(0x00); + addbyte(0x00); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index deaf53c20..82cc79cfd 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -931,6 +931,8 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); if (uop->imm_data) host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (uop->is_a16) + host_arm64_AND_IMM(block, REG_X0, REG_X0, 0xffff); if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { host_arm64_call(block, codegen_mem_load_byte); } else if (REG_IS_W(dest_size)) { diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index d8c223884..b6963562c 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -995,6 +995,8 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); if (uop->imm_data) host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (uop->is_a16) + host_arm_AND_IMM(block, REG_R0, REG_R0, 0xffff); if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { host_arm_BL(block, (uintptr_t) codegen_mem_load_byte); } else if (REG_IS_W(dest_size)) { diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 46af68e75..0233a4636 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -997,8 +997,13 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (uop->imm_data) { + if (uop->is_a16) { + host_x86_ADD16_REG_IMM(block, REG_SI, uop->imm_data); + } else { + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + } + } if (REG_IS_B(dest_size)) { host_x86_CALL(block, codegen_mem_load_byte); } else if (REG_IS_W(dest_size)) { diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index cd79b9b47..beaf85c17 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -981,8 +981,13 @@ codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (uop->imm_data) { + if (uop->is_a16) { + host_x86_ADD16_REG_IMM(block, REG_SI, uop->imm_data); + } else { + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + } + } if (REG_IS_B(dest_size)) { host_x86_CALL(block, codegen_mem_load_byte); } else if (REG_IS_W(dest_size)) { diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 9bd2f9afe..ff84c7ccd 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -340,6 +340,7 @@ typedef struct uop_t { void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; + int is_a16; int jump_dest_uop; int jump_list_next; void *jump_dest; @@ -364,6 +365,8 @@ uop_alloc(ir_data_t *ir, uint32_t uop_type) uop = &ir->uops[ir->wr_pos++]; + uop->is_a16 = 0; + uop->dest_reg_a = invalid_ir_reg; uop->src_reg_a = invalid_ir_reg; uop->src_reg_b = invalid_ir_reg; @@ -489,7 +492,12 @@ uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->is_a16 = 0; + if (src_reg_b == IREG_eaa16) { + uop->src_reg_b = codegen_reg_read(IREG_eaaddr); + uop->is_a16 = 1; + } else + uop->src_reg_b = codegen_reg_read(src_reg_b); uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); uop->imm_data = imm; } diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index 91e0f5d63..33e01d951 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -533,8 +533,8 @@ ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSE uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 2); \ uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ \ @@ -556,8 +556,8 @@ ropCWDE(UNUSED(codeblock_t *block), ir_data_t *ir, UNUSED(uint8_t opcode), UNUSE uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), (op_32 & 0x200) ? IREG_eaaddr : IREG_eaa16, 4); \ uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ \ diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index a3f000826..de67fde5a 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -169,6 +169,8 @@ struct [IREG_GS_limit_high] = { REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, [IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_eaa16] = { REG_WORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ diff --git a/src/codegen_new/codegen_reg.h b/src/codegen_new/codegen_reg.h index ebb90b42f..fd3cf279a 100644 --- a/src/codegen_new/codegen_reg.h +++ b/src/codegen_new/codegen_reg.h @@ -132,7 +132,9 @@ enum { IREG_GS_limit_high = 86, IREG_SS_limit_high = 87, - IREG_COUNT = 88, + IREG_eaa16 = 88, + + IREG_COUNT = 89, IREG_INVALID = 255, diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index ec40612ee..a4ea5802b 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -248,6 +248,19 @@ int checkio(uint32_t port, int mask); return 1; \ } +#define CHECK_READ_2OP(chseg, low, high, low2, high2) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || (low2 < (chseg)->limit_low) || (high2 > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) { \ + x86gpf("Limit check (READ)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } + #define CHECK_READ_REP(chseg, low, high) \ if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ x86gpf("Limit check (READ)", 0); \ @@ -277,6 +290,19 @@ int checkio(uint32_t port, int mask); #define CHECK_WRITE(chseg, low, high) \ CHECK_WRITE_COMMON(chseg, low, high) +#define CHECK_WRITE_2OP(chseg, low, high, low2, high2) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || (low2 < (chseg)->limit_low) || (high2 > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \ + x86gpf("Limit check (WRITE)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } + #define CHECK_WRITE_REP(chseg, low, high) \ if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ x86gpf("Limit check (WRITE REP)", 0); \ diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 80097294d..0e49704fd 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -335,7 +335,10 @@ typedef struct { uint8_t tag[8]; x86seg *ea_seg; - uint32_t eaaddr; + union { + uint32_t eaaddr; + uint16_t eaa16[2]; + }; int flags_op; uint32_t flags_res; diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 7fcc92312..a34bc0c70 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -272,9 +272,10 @@ opLDS_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); + CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 1, + ((cpu_state.eaa16[0] + 2) & 0xffff), ((cpu_state.eaa16[0] + 2) & 0xffff) + 1); + addr = readmemw(easeg, cpu_state.eaa16[0]); + seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff); if (cpu_state.abrt) return 1; op_loadseg(seg, &cpu_state.seg_ds); @@ -318,9 +319,10 @@ opLDS_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); + CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 3, + ((cpu_state.eaa16[0] + 4) & 0xffff), ((cpu_state.eaa16[0] + 4) & 0xffff) + 1); + addr = readmeml(easeg, cpu_state.eaa16[0]); + seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff); if (cpu_state.abrt) return 1; op_loadseg(seg, &cpu_state.seg_ds); @@ -365,9 +367,10 @@ opLSS_w_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); + CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 1, + ((cpu_state.eaa16[0] + 2) & 0xffff), ((cpu_state.eaa16[0] + 2) & 0xffff) + 1); + addr = readmemw(easeg, cpu_state.eaa16[0]); + seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff); if (cpu_state.abrt) return 1; op_loadseg(seg, &cpu_state.seg_ss); @@ -411,9 +414,11 @@ opLSS_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON(cpu_mod == 3); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); + CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 3, + ((cpu_state.eaa16[0] + 4) & 0xffff), ((cpu_state.eaa16[0] + 4) & 0xffff) + 1); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaa16[0], ((cpu_state.eaa16[0] + 5) & 0xffff)); + addr = readmeml(easeg, cpu_state.eaa16[0]); + seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff); if (cpu_state.abrt) return 1; op_loadseg(seg, &cpu_state.seg_ss); @@ -457,9 +462,9 @@ opLSS_l_a32(uint32_t fetchdat) fetch_ea_16(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 1, ((cpu_state.eaa16[0] + 2) & 0xffff), ((cpu_state.eaa16[0] + 2) & 0xffff) + 1); \ + addr = readmemw(easeg, cpu_state.eaa16[0]); \ + seg = readmemw(easeg, (cpu_state.eaa16[0] + 2) & 0xffff); \ if (cpu_state.abrt) \ return 1; \ op_loadseg(seg, &sel); \ @@ -502,9 +507,9 @@ opLSS_l_a32(uint32_t fetchdat) fetch_ea_16(fetchdat); \ SEG_CHECK_READ(cpu_state.ea_seg); \ ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + CHECK_READ_2OP(cpu_state.ea_seg, cpu_state.eaa16[0], cpu_state.eaa16[0] + 3, ((cpu_state.eaa16[0] + 4) & 0xffff), ((cpu_state.eaa16[0] + 4) & 0xffff) + 1); \ + addr = readmeml(easeg, cpu_state.eaa16[0]); \ + seg = readmemw(easeg, (cpu_state.eaa16[0] + 4) & 0xffff); \ if (cpu_state.abrt) \ return 1; \ op_loadseg(seg, &sel); \ diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 935fb5aa0..8bf72e9ed 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -15,7 +15,7 @@ op_loadcs(readmemw(ss, ESP + 2)); \ } else { \ cpu_state.pc = readmemw(ss, SP); \ - op_loadcs(readmemw(ss, SP + 2)); \ + op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \ } \ if (cpu_state.abrt) \ return 1; \ diff --git a/src/cpu/x86_ops_ret_2386.h b/src/cpu/x86_ops_ret_2386.h index 155925dfe..02233fd1d 100644 --- a/src/cpu/x86_ops_ret_2386.h +++ b/src/cpu/x86_ops_ret_2386.h @@ -15,7 +15,7 @@ op_loadcs(readmemw(ss, ESP + 2)); \ } else { \ cpu_state.pc = readmemw(ss, SP); \ - op_loadcs(readmemw(ss, SP + 2)); \ + op_loadcs(readmemw(ss, (SP + 2) & 0xffff)); \ } \ if (cpu_state.abrt) \ return 1; \ From 6884dc573688c4e16b71c218ccc676d8e5796d50 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 06:23:22 +0200 Subject: [PATCH 07/12] Old recompiler: Fix compile-breaking mistakes. --- src/codegen/codegen_ops_x86-64.h | 2 +- src/codegen/codegen_ops_x86.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 1be5dfdce..1d9b29de2 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -1055,7 +1055,7 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) addbyte(0xc0); addbyte(offset); if (!(op_32 & 0x200)) { - addbyte(0x25) /* AND EAX, ffffh */ + addbyte(0x25); /* AND EAX, ffffh */ addbyte(0xff); addbyte(0xff); addbyte(0x00); diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 7a56b5fe1..5e7165939 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -803,7 +803,7 @@ MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) addbyte(0xc0); addbyte(offset); if (!(op_32 & 0x200)) { - addbyte(0x25) /* AND EAX, ffffh */ + addbyte(0x25); /* AND EAX, ffffh */ addbyte(0xff); addbyte(0xff); addbyte(0x00); From 576d643c4f655affdc0b5d041d3ec97263c64bb2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 06:29:57 +0200 Subject: [PATCH 08/12] And fix the op_32 stuff. --- src/codegen/codegen_ops_mov.h | 4 ++-- src/codegen/codegen_ops_x86-64.h | 2 +- src/codegen/codegen_ops_x86.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen/codegen_ops_mov.h b/src/codegen/codegen_ops_mov.h index 6a5054b81..eb2a0202c 100644 --- a/src/codegen/codegen_ops_mov.h +++ b/src/codegen/codegen_ops_mov.h @@ -600,12 +600,12 @@ ropMOV_seg_w(UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t MEM_LOAD_ADDR_EA_L(target_seg); \ STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, 0); \ LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ + MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4, op_32); \ } else { \ MEM_LOAD_ADDR_EA_W(target_seg); \ STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, 0); \ LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ + MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2, op_32); \ } \ LOAD_SEG(0, &rseg); \ if (op_32 & 0x100) { \ diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 1d9b29de2..129d9a740 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -1049,7 +1049,7 @@ MEM_LOAD_ADDR_EA_W(x86seg *seg) /*done:*/ } static __inline void -MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset, int op_32) { addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 5e7165939..3fbefdeaa 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -789,7 +789,7 @@ MEM_LOAD_ADDR_EA_W(x86seg *seg) host_reg_mapping[0] = 8; } static __inline void -MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset, int op_32) { if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x31); /*XOR EDX, EDX*/ From fb449f39a44529f0cea0d1842145595f1425ee17 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 7 Apr 2025 07:41:59 +0200 Subject: [PATCH 09/12] Intel Premiere/PCI and Premiere/PCI II: Use a dual-channel IDE controller, fixes #5442. --- src/machine/m_at_socket4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index 0d78c6de3..c747d8cc0 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -47,7 +47,7 @@ machine_at_premiere_common_init(const machine_t *model, int pci_switch) machine_at_common_init_ex(model, 2); device_add(&amstrad_megapc_nvr_device); - device_add(&ide_pci_device); + device_add(&ide_pci_2ch_device); pci_init(PCI_CONFIG_TYPE_2 | pci_switch); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); From 44db8bb478eba862d66acbc4f9cc90336ff5d35c Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 7 Apr 2025 11:42:03 +0600 Subject: [PATCH 10/12] Fix compilation on Qt6 --- src/qt/qt_mainwindow.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 806e8e0e6..e9ebdaad8 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -674,7 +674,11 @@ MainWindow::MainWindow(QWidget *parent) /* Remove default Shift+F10 handler, which unfocuses keyboard input even with no context menu. */ connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, [](){}); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + auto windowedShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_PageDown), this); +#else auto windowedShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_PageDown), this); +#endif windowedShortcut->setContext(Qt::ShortcutContext::ApplicationShortcut); connect(windowedShortcut, &QShortcut::activated, this, [this] () { if (video_fullscreen) From ebf125082a951752f3b3a819daf6e115a2fc1175 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 7 Apr 2025 20:33:50 +0200 Subject: [PATCH 11/12] Revert a minor commit from Spock. (April 7th, 2025) This fixes OS/2 Warp on a PS/2 machine using the Spock/Tribble during the file copy phase (the bug was probably too many IRQ's being fired). --- src/scsi/scsi_spock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index c500abfbc..6f0b7aacb 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -1050,7 +1050,7 @@ spock_callback(void *priv) spock_execute_cmd(scsi, scb); } - if (scsi->attention_wait) { + if (scsi->attention_wait && ((scsi->scb_state == 0) || (scsi->attention_pending & 0xf0) == 0xe0)) { scsi->attention_wait--; if (!scsi->attention_wait) { scsi->attention = scsi->attention_pending; From f5fcebfbaa7552fc5533a1752ab0f0ea8e953fb8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 9 Apr 2025 12:19:24 +0200 Subject: [PATCH 12/12] Default the language to the system language. --- src/config.c | 2 ++ src/include/86box/86box.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index 8ff7d548c..f38b5aa2c 100644 --- a/src/config.c +++ b/src/config.c @@ -1840,6 +1840,8 @@ config_load(void) cassette_pcm = 0; cassette_ui_writeprot = 0; + lang_id = DEFAULT_LANGUAGE; + config_log("Config file not present or invalid!\n"); } else { load_general(); /* General */ diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 61de69cf3..ddca937f1 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -45,7 +45,7 @@ #define MAX_UUID_LEN 64 /* Default language 0xFFFF = from system, 0x409 = en-US */ -#define DEFAULT_LANGUAGE 0x0409 +#define DEFAULT_LANGUAGE 0xffff #define POSTCARDS_NUM 4 #define POSTCARD_MASK (POSTCARDS_NUM - 1)