From 080632bd4a4f29da112f477d55e4424fe2c40e42 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 25 Oct 2025 22:20:25 -0500 Subject: [PATCH 1/6] Initial implementation of the Crystal CS4232 audio controller --- src/include/86box/sound.h | 1 + src/sound/snd_cs423x.c | 58 +++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 2280824e4..c2b41776f 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -177,6 +177,7 @@ extern const device_t sb_awe64_ide_device; extern const device_t sb_awe64_gold_device; /* Crystal CS423x */ +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/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 78b628b3b..10eb27cf2 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -88,6 +88,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 +402,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 +830,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 +867,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. */ @@ -890,6 +920,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,13 +928,16 @@ 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. */ @@ -1056,6 +1090,20 @@ cs423x_speed_changed(void *priv) ad1848_speed_changed(&dev->ad1848); } +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", From 7b40cfb563de413464ea8d8086f77e4d8123617a Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 25 Oct 2025 23:01:39 -0500 Subject: [PATCH 2/6] Give the Intel Atlantis, Monaco and Thor boards their onboard CS4232 audio --- src/machine/m_at_socket7_3v.c | 31 ++++++++++--------------------- src/machine/machine_table.c | 12 ++++++------ 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 07faa9f9f..04505d0fd 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_monaco_gpio_init machine_at_atlantis_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 7628d29fa..b65dd5d51 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'. */ From 69b05d5bfc88fefda83f5cb4c0cfcf22f7307b22 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 25 Oct 2025 23:05:28 -0500 Subject: [PATCH 3/6] Correct flipped names in GPIO define --- src/machine/m_at_socket7_3v.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 04505d0fd..7336c36d0 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -668,7 +668,7 @@ machine_at_endeavor_init(const machine_t *model) } /* The Monaco and Atlantis share the same GPIO config */ -#define machine_at_monaco_gpio_init machine_at_atlantis_gpio_init +#define machine_at_atlantis_gpio_init machine_at_monaco_gpio_init int machine_at_atlantis_init(const machine_t *model) From f4f050d14e09eb2e5318dbbe02b4e5f89fb81ca8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Oct 2025 17:42:10 +0100 Subject: [PATCH 4/6] Bump the version number to 6.0... again. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- src/unix/assets/86Box.spec | 4 ++-- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) 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/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/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 27805a9e4..e71497698 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 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", From cf6149c1c7c8fdddd2a12d8d6687837beb2e2d68 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 26 Oct 2025 13:59:33 -0300 Subject: [PATCH 5/6] bumpversion: Fix romset version patching and rework patching function to allow for multiple files [skip ci] --- bumpversion.sh | 46 +++++++++++++++++++++++--------------- src/unix/assets/86Box.spec | 2 +- 2 files changed, 29 insertions(+), 19 deletions(-) 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/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index e71497698..35916ffff 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,7 +12,7 @@ # 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: 6.0 From 8d12c46a3a2ea261502068cb071d0b68a932d09d Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sun, 26 Oct 2025 15:49:21 -0500 Subject: [PATCH 6/6] Add a generic discrete CS4232 sound card --- src/include/86box/sound.h | 1 + src/sound/snd_cs423x.c | 62 ++++++++++++++++++++++++++++++++------- src/sound/sound.c | 3 +- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index c2b41776f..ff096e0be 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -177,6 +177,7 @@ 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; diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 10eb27cf2..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 @@ -880,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"); } @@ -944,16 +948,30 @@ cs423x_init(const device_t *info) 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. */ @@ -966,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; @@ -1076,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) { @@ -1090,6 +1118,20 @@ 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", 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 +}