diff --git a/CMakeLists.txt b/CMakeLists.txt
index 29fedd6ad..2f6c18af0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,7 @@ if(MUNT_EXTERNAL)
endif()
project(86Box
- VERSION 5.2
+ VERSION 6.0
DESCRIPTION "Emulator of x86-based systems"
HOMEPAGE_URL "https://86box.net"
LANGUAGES C CXX)
diff --git a/bumpversion.sh b/bumpversion.sh
index 6e2536cbe..76ef07554 100644
--- a/bumpversion.sh
+++ b/bumpversion.sh
@@ -43,23 +43,33 @@ pretty_date() {
# Patch files.
patch_file() {
- # Stop if the file doesn't exist.
- [ ! -e "$1" ] && return
+ # Parse arguments.
+ desc="$1"
+ shift
+ pattern="$1"
+ shift
- # Patch file.
- if sed -i -r -e "$3" "$1"
- then
- echo "[-] Patched $2 on $1"
- else
- echo "[!] Patching $2 on $1 failed"
- fi
+ # Patch the specified files.
+ for file in "$@"
+ do
+ # Skip file if it doesn't exist.
+ [ ! -e "$file" ] && continue
+
+ # Patch file.
+ if sed -i -r -e "$pattern" "$file"
+ then
+ echo "[-] Patched $desc in $file"
+ else
+ echo "[!] Patching $desc in $file failed"
+ fi
+ done
}
-patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/'
-patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/'
-patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/'
-patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/'
-patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/'
-patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/'
-patch_file src/unix/assets/*.metainfo.xml release 's/( .+/> '"$(date -R)"'/'
-patch_file debian/changelog 'changelog version' 's/86box \(.+\)/86box \('"$newversion"'\)/'
+patch_file VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/' CMakeLists.txt
+patch_file version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/' vcpkg.json
+patch_file Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' src/unix/assets/*.spec
+patch_file '%global romver' 's/(^%global\ romver\s+)[^\s]+/\1'"$romversion"'/' src/unix/assets/*.spec
+patch_file 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' src/unix/assets/*.spec
+patch_file 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' src/unix/assets/*.spec
+patch_file release 's/( .+/> '"$(date -R)"'/' debian/changelog
+patch_file 'changelog version' 's/86box \(.+\)/86box \('"$newversion"'\)/' debian/changelog
diff --git a/debian/changelog b/debian/changelog
index cfb4bd9d0..d2606a616 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,5 @@
-86box (5.2) UNRELEASED; urgency=medium
+86box (6.0) UNRELEASED; urgency=medium
* Bump release.
- -- Jasmine Iwanek Thu, 18 Sep 2025 04:25:57 +0200
+ -- Jasmine Iwanek Sun, 26 Oct 2025 17:41:47 +0100
diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h
index 2280824e4..ff096e0be 100644
--- a/src/include/86box/sound.h
+++ b/src/include/86box/sound.h
@@ -177,6 +177,8 @@ extern const device_t sb_awe64_ide_device;
extern const device_t sb_awe64_gold_device;
/* Crystal CS423x */
+extern const device_t cs4232_device;
+extern const device_t cs4232_onboard_device;
extern const device_t cs4235_device;
extern const device_t cs4235_onboard_device;
extern const device_t cs4236_onboard_device;
diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c
index 07faa9f9f..7336c36d0 100644
--- a/src/machine/m_at_socket7_3v.c
+++ b/src/machine/m_at_socket7_3v.c
@@ -435,6 +435,9 @@ machine_at_thor_gpio_init(void)
else if (cpu_busspeed > 60000000)
gpio |= 0xffff1000;
+ if (sound_card_current[0] == SOUND_INTERNAL)
+ gpio |= 0xffff0400;
+
machine_set_gpio_default(gpio);
}
@@ -476,6 +479,9 @@ machine_at_thor_init(const machine_t *model)
if (has_video && (gfxcard[0] == VID_INTERNAL))
device_add(machine_get_vid_device(machine));
+ if (has_video && (sound_card_current[0] == SOUND_INTERNAL))
+ machine_snd = device_add(machine_get_snd_device(machine));
+
device_add(&i430fx_device);
device_add(&piix_device);
device_add_params(&pc87306_device, (void *) PCX730X_AMI);
@@ -576,27 +582,6 @@ machine_at_monaco_gpio_init(void)
{
uint32_t gpio = 0xffffe0cf;
- /* Return to this after CS4232 PnP is working. */
- /* Register 0x0078 (Undocumented): */
- /* Bit 5,4: Vibra 16S base address: 0 = 220h, 1 = 260h, 2 = 240h, 3 = 280h. */
- /*device_context(machine_get_snd_device(machine));
- addr = device_get_config_hex16("base");
- switch (addr) {
- case 0x0220:
- gpio |= 0xffff00cf;
- break;
- case 0x0240:
- gpio |= 0xffff00ef;
- break;
- case 0x0260:
- gpio |= 0xffff00df;
- break;
- case 0x0280:
- gpio |= 0xffff00ff;
- break;
- }
- device_context_restore();*/
-
/* Register 0x0079: */
/* Bit 7: 0 = Clear password, 1 = Keep password. */
/* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */
@@ -682,6 +667,9 @@ machine_at_endeavor_init(const machine_t *model)
return ret;
}
+/* The Monaco and Atlantis share the same GPIO config */
+#define machine_at_atlantis_gpio_init machine_at_monaco_gpio_init
+
int
machine_at_atlantis_init(const machine_t *model)
{
@@ -695,6 +683,7 @@ machine_at_atlantis_init(const machine_t *model)
return ret;
machine_at_common_init_ex(model, 2);
+ machine_at_atlantis_gpio_init();
pci_init(PCI_CONFIG_TYPE_1);
pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0);
diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c
index fe3f4da6e..9f9eecc0b 100644
--- a/src/machine/machine_table.c
+++ b/src/machine/machine_table.c
@@ -13488,7 +13488,7 @@ const machine_t machines[] = {
.max_multi = 3.0
},
.bus_flags = MACHINE_PS2_PCI,
- .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */
+ .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */
.ram = {
.min = 8192,
.max = 131072,
@@ -13507,7 +13507,7 @@ const machine_t machines[] = {
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &mach64ct_device_onboard,
- .snd_device = NULL,
+ .snd_device = &cs4232_onboard_device,
.net_device = NULL
},
/* According to tests from real hardware: This has AMI MegaKey KBC firmware on the
@@ -13534,7 +13534,7 @@ const machine_t machines[] = {
.max_multi = 3.0
},
.bus_flags = MACHINE_PS2_PCI,
- .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has optional onboard sound: Crystal CS4232-KQ */
+ .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_SOUND | MACHINE_GAMEPORT, /* Machine has optional onboard sound: Crystal CS4232-KQ */
.ram = {
.min = 8192,
.max = 131072,
@@ -13553,7 +13553,7 @@ const machine_t machines[] = {
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &s3_phoenix_trio64vplus_onboard_pci_device,
- .snd_device = NULL,
+ .snd_device = &cs4232_onboard_device,
.net_device = NULL
},
/* According to tests from real hardware: This has AMI MegaKey KBC firmware on the
@@ -13626,7 +13626,7 @@ const machine_t machines[] = {
.max_multi = 3.0
},
.bus_flags = MACHINE_PS2_PCI,
- .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */
+ .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */
.ram = {
.min = 8192,
.max = 131072,
@@ -13645,7 +13645,7 @@ const machine_t machines[] = {
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = &mach64ct_device_onboard,
- .snd_device = NULL,
+ .snd_device = &cs4232_onboard_device,
.net_device = NULL
},
/* This has an AMIKey-2, which is type 'H'. */
diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c
index 78b628b3b..4fd630e07 100644
--- a/src/sound/snd_cs423x.c
+++ b/src/sound/snd_cs423x.c
@@ -40,6 +40,7 @@
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
+#define PNP_ROM_CS4232 "roms/sound/crystal/CS4232.BIN"
#define PNP_ROM_CS4236B "roms/sound/crystal/PNPISA01.BIN"
#define CRYSTAL_NOEEPROM 0x100
@@ -88,6 +89,20 @@ static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0
0x5E, 0xAF, 0x57, 0x2B, 0x15, 0x8A, 0xC5, 0xE2,
0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13,
0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A };
+
+static const uint8_t cs4232_default[] = {
+ // clang-format off
+ /* Chip configuration */
+ 0x00, /* external decode length */
+ 0x48, /* reserved */
+ 0x75, 0xb9, 0xfc, /* IRQ routing */
+ 0x10, 0x03, /* DMA routing */
+
+ /* Default PnP data */
+ 0x0e, 0x63, 0x42, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00 /* hinted by documentation to be just the header */
+ // clang-format on
+};
+
static const uint8_t cs4236_default[] = {
// clang-format off
/* Chip configuration */
@@ -388,9 +403,17 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv)
case 6: /* RAM Access End */
/* TriGem Delhi-III BIOS writes undocumented value 0x40 instead of 0x00. */
- if ((val == 0x00) || (val == 0x40)) {
+ /* Intel Atlantis, Holly, Monaco, Morrison and Thor BIOSes use several undocumented values */
+ /* 0x25, 0x60, 0x69, 0x86, 0xE2, 0xFE and 0xFF were observed on these BIOSes */
+ /* CS4232 likely accepts any written value to end RAM writes */
+ if ((val == 0x00) || (val == 0x40) || (dev->type == CRYSTAL_CS4232)) {
cs423x_log("CS423x: RAM end\n");
dev->ram_dl = CRYSTAL_RAM_CMD;
+ /* CS4232 resource data at 0x2090/2091 is written backwards */
+ if (dev->type == CRYSTAL_CS4232) {
+ dev->ram_data[0x2090] = 0x00;
+ dev->ram_data[0x2091] = 0x48;
+ }
/* Update PnP state and resource data. */
dev->pnp_size = (dev->type >= CRYSTAL_CS4236) ? 384 : 256; /* we don't know the length */
@@ -808,6 +831,10 @@ static void
cs423x_load_defaults(cs423x_t *dev, uint8_t *dest)
{
switch (dev->type) {
+ case CRYSTAL_CS4232:
+ memcpy(dest, cs4232_default, sizeof(cs4232_default));
+ dev->pnp_size = 9; /* header-only PnP ROM size */
+ break;
case CRYSTAL_CS4236:
case CRYSTAL_CS4236B:
case CRYSTAL_CS4237B:
@@ -841,7 +868,11 @@ cs423x_reset(void *priv)
memset(dev->ram_data, 0, sizeof(dev->ram_data));
/* Load default configuration data to RAM. */
- cs423x_load_defaults(dev, &dev->ram_data[0x4000]);
+ /* CS4232 uses 0x2090 as the initial RAM location instead of 0x4000 */
+ if (dev->type == CRYSTAL_CS4232)
+ cs423x_load_defaults(dev, &dev->ram_data[0x2090]);
+ else
+ cs423x_load_defaults(dev, &dev->ram_data[0x4000]);
if (dev->eeprom) {
/* Load EEPROM data to RAM if the magic bytes are present. */
@@ -850,7 +881,10 @@ cs423x_reset(void *priv)
dev->pnp_size = (dev->eeprom_data[2] << 8) | dev->eeprom_data[3];
if (dev->pnp_size > 384)
dev->pnp_size = 384;
- memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4);
+ if (dev->type == CRYSTAL_CS4232)
+ memcpy(&dev->ram_data[0x2090], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4);
+ else
+ memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4);
} else {
cs423x_log("CS423x: EEPROM data invalid, ignoring\n");
}
@@ -890,6 +924,7 @@ cs423x_init(const device_t *info)
dev->type = info->local & 0xff;
cs423x_log("CS423x: init(%02X)\n", dev->type);
switch (dev->type) {
+ case CRYSTAL_CS4232:
case CRYSTAL_CS4236:
case CRYSTAL_CS4236B:
case CRYSTAL_CS4237B:
@@ -897,29 +932,46 @@ cs423x_init(const device_t *info)
case CRYSTAL_CS4235:
case CRYSTAL_CS4239:
/* Different WSS codec families. */
- dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : AD1848_TYPE_CS4236);
+ dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : (dev->type >= CRYSTAL_CS4236) ? AD1848_TYPE_CS4236 : AD1848_TYPE_CS4232);
/* Different Chip Version and ID values (N/A on CS4236), which shouldn't be reset by ad1848_init. */
dev->ad1848.xregs[25] = dev->type;
- /* Same EEPROM structure. */
- dev->pnp_offset = 0x4013;
+ /* Same EEPROM structure on CS4236+. CS4232 is different. */
+ if (dev->type == CRYSTAL_CS4232)
+ dev->pnp_offset = 0x2097;
+ else
+ dev->pnp_offset = 0x4013;
if (!(info->local & CRYSTAL_NOEEPROM)) {
/* Start a new EEPROM with the default configuration data. */
cs423x_load_defaults(dev, &dev->eeprom_data[4]);
/* Load PnP resource data ROM. */
- FILE *fp = rom_fopen(PNP_ROM_CS4236B, "rb");
- if (fp) {
- uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x1ff) + 4;
- /* This is wrong. The header field only indicates PnP resource data length, and real chips use
- it to locate the firmware patch area, but we don't need any of that, so we can get away
- with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */
- dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp);
- fclose(fp);
+ if (dev->type == CRYSTAL_CS4232) {
+ FILE *fp = rom_fopen(PNP_ROM_CS4232, "rb");
+ if (fp) {
+ uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x0f) + 4;
+ /* This is wrong. The header field only indicates PnP resource data length, and real chips use
+ it to locate the firmware patch area, but we don't need any of that, so we can get away
+ with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */
+ dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp);
+ fclose(fp);
+ } else {
+ dev->pnp_size = 0;
+ }
} else {
- dev->pnp_size = 0;
+ FILE *fp = rom_fopen(PNP_ROM_CS4236B, "rb");
+ if (fp) {
+ uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x1ff) + 4;
+ /* This is wrong. The header field only indicates PnP resource data length, and real chips use
+ it to locate the firmware patch area, but we don't need any of that, so we can get away
+ with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */
+ dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp);
+ fclose(fp);
+ } else {
+ dev->pnp_size = 0;
+ }
}
/* Populate EEPROM header if the PnP ROM was loaded. */
@@ -932,6 +984,10 @@ cs423x_init(const device_t *info)
/* Patch PnP ROM and set EEPROM file name. */
switch (dev->type) {
+ case CRYSTAL_CS4232:
+ dev->nvr_path = "cs4232.nvr";
+ break;
+
case CRYSTAL_CS4236:
if (dev->pnp_size) {
dev->eeprom_data[26] = 0x36;
@@ -1042,6 +1098,12 @@ cs423x_close(void *priv)
free(dev);
}
+static int
+cs4232_available(void)
+{
+ return rom_present(PNP_ROM_CS4232);
+}
+
static int
cs423x_available(void)
{
@@ -1056,6 +1118,34 @@ cs423x_speed_changed(void *priv)
ad1848_speed_changed(&dev->ad1848);
}
+const device_t cs4232_device = {
+ .name = "Crystal CS4232",
+ .internal_name = "cs4232",
+ .flags = DEVICE_ISA16,
+ .local = CRYSTAL_CS4232,
+ .init = cs423x_init,
+ .close = cs423x_close,
+ .reset = cs423x_reset,
+ .available = cs4232_available,
+ .speed_changed = cs423x_speed_changed,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
+const device_t cs4232_onboard_device = {
+ .name = "Crystal CS4232 (On-Board)",
+ .internal_name = "cs4232_onboard",
+ .flags = DEVICE_ISA16,
+ .local = CRYSTAL_CS4232 | CRYSTAL_NOEEPROM,
+ .init = cs423x_init,
+ .close = cs423x_close,
+ .reset = cs423x_reset,
+ .available = cs423x_available,
+ .speed_changed = cs423x_speed_changed,
+ .force_redraw = NULL,
+ .config = NULL
+};
+
const device_t cs4235_device = {
.name = "Crystal CS4235",
.internal_name = "cs4235",
diff --git a/src/sound/sound.c b/src/sound/sound.c
index 9373f067e..7b4141bd8 100644
--- a/src/sound/sound.c
+++ b/src/sound/sound.c
@@ -140,6 +140,7 @@ static const SOUND_CARD sound_cards[] = {
{ &azt2316a_device },
{ &azt1605_device },
{ &sb_goldfinch_device },
+ { &cs4232_device },
{ &cs4235_device },
{ &cs4236b_device },
{ &gus_device },
@@ -849,4 +850,4 @@ sound_fdd_thread_end(void)
sound_fdd_start_event = NULL;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec
index 27805a9e4..35916ffff 100644
--- a/src/unix/assets/86Box.spec
+++ b/src/unix/assets/86Box.spec
@@ -12,10 +12,10 @@
# After a successful build, you can install the RPMs as follows:
# sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms*
-%global romver 4.1
+%global romver 5.2
Name: 86Box
-Version: 5.2
+Version: 6.0
Release: 1%{?dist}
Summary: Classic PC emulator
License: GPLv2+
@@ -121,5 +121,5 @@ popd
%{_datadir}/%{name}/roms
%changelog
-* Sat Aug 31 Jasmine Iwanek 5.2-1
+* Sat Aug 31 Jasmine Iwanek 6.0-1
- Bump release
diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml
index fd633d426..1e929412c 100644
--- a/src/unix/assets/net.86box.86Box.metainfo.xml
+++ b/src/unix/assets/net.86box.86Box.metainfo.xml
@@ -11,7 +11,7 @@
net.86box.86Box.desktop
-
+
diff --git a/vcpkg.json b/vcpkg.json
index 73f6d08f8..6a4f6376c 100644
--- a/vcpkg.json
+++ b/vcpkg.json
@@ -1,6 +1,6 @@
{
"name": "86box",
- "version-string": "5.2",
+ "version-string": "6.0",
"homepage": "https://86box.net/",
"documentation": "https://86box.readthedocs.io/",
"license": "GPL-2.0-or-later",