From 66e334757eb9319e18485be89babf31e2fb989e1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 10 Oct 2023 00:18:13 +0200 Subject: [PATCH] The Vibra 16C is now correctly PnP and added standalone Vibra 16S, 16XV, and 16C, as well as Intel CU430HX, the non-OEM version of the Toshiba Equium 5200. --- src/include/86box/machine.h | 2 +- src/include/86box/sound.h | 3 + src/machine/m_at_socket7.c | 120 ++++++++----------- src/machine/machine_table.c | 42 ++++++- src/sound/snd_sb.c | 231 +++++++++++++++++++++++++++++++++++- src/sound/sound.c | 3 + 6 files changed, 322 insertions(+), 79 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 29df64713..8af7f65ea 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -647,7 +647,7 @@ extern int machine_at_p55t2p4_init(const machine_t *); extern int machine_at_m7shi_init(const machine_t *); extern int machine_at_tc430hx_init(const machine_t *); extern int machine_at_infinia7200_init(const machine_t *); -extern uint32_t machine_at_cu430hx_gpio_handler(uint8_t write, uint32_t val); +extern int machine_at_cu430hx_init(const machine_t *); extern int machine_at_equium5200_init(const machine_t *); extern int machine_at_pcv90_init(const machine_t *); extern int machine_at_p65up5_cp55t2d_init(const machine_t *); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 2d9d7b6bc..28dda0c02 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -132,7 +132,10 @@ extern const device_t sb_pro_mcv_device; extern const device_t sb_pro_compat_device; extern const device_t sb_16_device; extern const device_t sb_vibra16s_onboard_device; +extern const device_t sb_vibra16s_device; +extern const device_t sb_vibra16xv_device; extern const device_t sb_vibra16c_onboard_device; +extern const device_t sb_vibra16c_device; extern const device_t sb_16_pnp_device; extern const device_t sb_16_compat_device; extern const device_t sb_16_compat_nompu_device; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7564da84a..a698c9a35 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -182,7 +182,7 @@ machine_at_m7shi_init(const machine_t *model) static void machine_at_tc430hx_gpio_init(void) { - uint32_t gpio = 0xffffffff; + uint32_t gpio = 0xffffe1ff; /* Register 0x0079: */ /* Bit 7: 0 = Clear password, 1 = Keep password. */ @@ -197,8 +197,6 @@ machine_at_tc430hx_gpio_init(void) /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ /* Bit 0: 0 = Reserved. */ /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ - gpio = 0xffffe1ff; - if (cpu_busspeed <= 50000000) gpio |= 0xffff10ff; else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) @@ -290,28 +288,7 @@ machine_at_infinia7200_init(const machine_t *model) static void machine_at_cu430hx_gpio_init(void) { - uint32_t gpio = 0xffffe1cf; - uint16_t addr; - - /* Register 0x0078: */ - /* Bit 5,4: Vibra 16C 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(); + uint32_t gpio = 0xffffe1ff; /* Register 0x0079: */ /* Bit 7: 0 = Clear password, 1 = Keep password. */ @@ -327,48 +304,64 @@ machine_at_cu430hx_gpio_init(void) /* Bit 0: 0 = Reserved. */ /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ if (cpu_busspeed <= 50000000) - gpio |= 0xffff10cf; + gpio |= 0xffff10ff; else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) - gpio |= 0xffff18cf; + gpio |= 0xffff18ff; else if (cpu_busspeed > 60000000) - gpio |= 0xffff00cf; + gpio |= 0xffff00ff; if (sound_card_current[0] == SOUND_INTERNAL) - gpio |= 0xffff04cf; + gpio |= 0xffff04ff; machine_set_gpio_default(gpio); } -uint32_t -machine_at_cu430hx_gpio_handler(uint8_t write, uint32_t val) +static void +machine_at_cu430hx_common_init(const machine_t *model) { - uint32_t ret = machine_get_gpio_default(); + machine_at_common_init_ex(model, 2); + machine_at_cu430hx_gpio_init(); - if (write) { - ret &= ((val & 0xffffffcf) | 0xffff0000); - ret |= (val & 0x00000030); - if (machine_snd != NULL) switch ((val >> 4) & 0x03) { - case 0x00: - sb_vibra16c_onboard_relocate_base(0x0220, machine_snd); - break; - case 0x01: - sb_vibra16c_onboard_relocate_base(0x0260, machine_snd); - break; - case 0x02: - sb_vibra16c_onboard_relocate_base(0x0240, machine_snd); - break; - case 0x03: - sb_vibra16c_onboard_relocate_base(0x0280, machine_snd); - break; - } - machine_set_gpio(ret); - } else - ret = machine_get_gpio(); + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); // ATI VGA Graphics + pci_register_slot(0x0C, PCI_CARD_NETWORK, 4, 0, 0, 0); // Intel 82557 Ethernet Network + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + + device_add(&i430hx_device); + device_add(&piix3_device); + device_add(&keyboard_ps2_ami_pci_device); + device_add(&pc87306_device); + device_add(&intel_flash_bxt_ami_device); +} + +int +machine_at_cu430hx_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/cu430hx/1006DK0_.BIO", + "roms/machines/cu430hx/1006DK0_.BI1", + "roms/machines/cu430hx/1006DK0_.BI2", + "roms/machines/cu430hx/1006DK0_.BI3", + "roms/machines/cu430hx/1006DK0_.RCV", + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_cu430hx_common_init(model); return ret; } -/* Information about that machine on machine.h */ int machine_at_equium5200_init(const machine_t *model) { @@ -384,26 +377,7 @@ machine_at_equium5200_init(const machine_t *model) if (bios_only || !ret) return ret; - machine_at_common_init_ex(model, 2); - machine_at_cu430hx_gpio_init(); - - pci_init(PCI_CONFIG_TYPE_1); - pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); - pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x0B, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0A, PCI_CARD_NORMAL, 3, 0, 0, 0); // riser - - if (sound_card_current[0] == SOUND_INTERNAL) - machine_snd = device_add(machine_get_snd_device(machine)); - - device_add(&i430hx_device); - device_add(&piix3_device); - device_add(&keyboard_ps2_ami_pci_device); - device_add(&pc87306_device); - device_add(&intel_flash_bxt_ami_device); + machine_at_cu430hx_common_init(model); return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 4a8a2a757..c2bc31495 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -9815,6 +9815,46 @@ const machine_t machines[] = { .net_device = NULL }, /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ + { + .name = "[i430HX] Intel CU430HX", + .internal_name = "cu430hx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_cu430hx_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI, + .ram = { + .min = 8192, + .max = 196608, + .step = 8192 + }, + .nvrmask = 255, + .kbc_device = NULL, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &sb_vibra16c_onboard_device, + .net_device = NULL + }, + /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ { .name = "[i430HX] Toshiba Equium 5200D", .internal_name = "equium5200", @@ -9822,7 +9862,7 @@ const machine_t machines[] = { .chipset = MACHINE_CHIPSET_INTEL_430HX, .init = machine_at_equium5200_init, .p1_handler = NULL, - .gpio_handler = machine_at_cu430hx_gpio_handler, + .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 107507d77..ffb5240b8 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -1537,6 +1537,100 @@ sb_16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) } } +static void +sb_vibra16_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) +{ + sb_t *sb = (sb_t *) priv; + uint16_t addr = sb->dsp.sb_addr; + uint8_t val; + + switch (ld) { + case 0: /* Audio */ + io_removehandler(addr, 0x0004, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_removehandler(addr + 8, 0x0002, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_removehandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); + + addr = sb->opl_pnp_addr; + if (addr) { + sb->opl_pnp_addr = 0; + io_removehandler(addr, 0x0004, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + } + + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, 0); + sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); + + mpu401_change_addr(sb->mpu, 0); + + if (config->activate) { + addr = config->io[0].base; + if (addr != ISAPNP_IO_DISABLED) { + io_sethandler(addr, 0x0004, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_sethandler(addr + 8, 0x0002, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + io_sethandler(addr + 4, 0x0002, + sb_ct1745_mixer_read, NULL, NULL, + sb_ct1745_mixer_write, NULL, NULL, + sb); + + sb_dsp_setaddr(&sb->dsp, addr); + } + + addr = config->io[1].base; + if (addr != ISAPNP_IO_DISABLED) + mpu401_change_addr(sb->mpu, addr); + + addr = config->io[2].base; + if (addr != ISAPNP_IO_DISABLED) { + sb->opl_pnp_addr = addr; + io_sethandler(addr, 0x0004, + sb->opl.read, NULL, NULL, + sb->opl.write, NULL, NULL, + sb->opl.priv); + } + + val = config->irq[0].irq; + if (val != ISAPNP_IRQ_DISABLED) + sb_dsp_setirq(&sb->dsp, val); + + val = config->dma[0].dma; + if (val != ISAPNP_DMA_DISABLED) + sb_dsp_setdma8(&sb->dsp, val); + + val = config->dma[1].dma; + if (val != ISAPNP_DMA_DISABLED) + sb_dsp_setdma16(&sb->dsp, val); + } + + break; + + case 1: /* Game */ + gameport_remap(sb->gameport, (config->activate && (config->io[0].base != ISAPNP_IO_DISABLED)) ? config->io[0].base : 0); + break; + + default: + break; + } +} + static void sb_awe32_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) { @@ -2112,6 +2206,93 @@ sb_16_pnp_init(UNUSED(const device_t *info)) return sb; } +static int +sb_vibra16xv_available(void) +{ + return rom_present("roms/sound/CT4170 PnP.BIN"); +} + +static int +sb_vibra16c_available(void) +{ + return rom_present("roms/sound/CT4180 PnP.BIN"); +} + +static void * +sb_vibra16_pnp_init(UNUSED(const device_t *info)) +{ + sb_t *sb = malloc(sizeof(sb_t)); + memset(sb, 0x00, sizeof(sb_t)); + + sb->opl_enabled = 1; + fm_driver_get(FM_YMF262, &sb->opl); + + sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_ct1745_mixer_reset(sb); + + sb->mixer_enabled = 1; + sb->mixer_sb16.output_filter = 1; + sound_add_handler(sb_get_buffer_sb16_awe32, sb); + sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb); + + sb->mpu = (mpu_t *) malloc(sizeof(mpu_t)); + memset(sb->mpu, 0, sizeof(mpu_t)); + mpu401_init(sb->mpu, 0, 0, M_UART, device_get_config_int("receive_input401")); + sb_dsp_set_mpu(&sb->dsp, sb->mpu); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp); + + sb->gameport = gameport_add(&gameport_pnp_device); + + const char *pnp_rom_file = NULL; + switch (info->local) { + case 0: + pnp_rom_file = "roms/sound/CT4170 PnP.BIN"; + break; + + case 1: + pnp_rom_file = "roms/sound/CT4180 PnP.BIN"; + break; + + default: + break; + } + + uint8_t *pnp_rom = NULL; + if (pnp_rom_file) { + FILE *fp = rom_fopen(pnp_rom_file, "rb"); + if (fp) { + if (fread(sb->pnp_rom, 1, 512, fp) == 512) + pnp_rom = sb->pnp_rom; + fclose(fp); + } + } + + switch (info->local) { + case 0: + case 1: + isapnp_add_card(pnp_rom, sizeof(sb->pnp_rom), sb_vibra16_pnp_config_changed, + NULL, NULL, NULL, sb); + break; + + default: + break; + } + + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, 0); + sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED); + sb_dsp_setdma16(&sb->dsp, ISAPNP_DMA_DISABLED); + + mpu401_change_addr(sb->mpu, 0); + + sb->gameport_addr = 0; + gameport_remap(sb->gameport, 0); + + return sb; +} + static void * sb_16_compat_init(const device_t *info) { @@ -3693,11 +3874,11 @@ const device_t sb_vibra16s_onboard_device = { .config = sb_16_config }; -const device_t sb_vibra16c_onboard_device = { - .name = "Sound Blaster Vibra 16C (On-Board)", - .internal_name = "sb_vibra16c_onboard", +const device_t sb_vibra16s_device = { + .name = "Sound Blaster Vibra 16S", + .internal_name = "sb_vibra16s", .flags = DEVICE_ISA | DEVICE_AT, - .local = FM_YMF262, /* Should have the CQM but we do not emulate that yet. */ + .local = FM_YMF289B, .init = sb_16_init, .close = sb_close, .reset = NULL, @@ -3707,6 +3888,48 @@ const device_t sb_vibra16c_onboard_device = { .config = sb_16_config }; +const device_t sb_vibra16xv_device = { + .name = "Sound Blaster Vibra 16XV", + .internal_name = "sb_vibra16xv", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = sb_vibra16xv_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16c_onboard_device = { + .name = "Sound Blaster Vibra 16C (On-Board)", + .internal_name = "sb_vibra16c_onboard", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + +const device_t sb_vibra16c_device = { + .name = "Sound Blaster Vibra 16C", + .internal_name = "sb_vibra16c", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 1, + .init = sb_vibra16_pnp_init, + .close = sb_close, + .reset = NULL, + { .available = sb_vibra16c_available }, + .speed_changed = sb_speed_changed, + .force_redraw = NULL, + .config = sb_16_pnp_config +}; + const device_t sb_16_reply_mca_device = { .name = "Sound Blaster 16 Reply MCA", .internal_name = "sb16_reply_mca", diff --git a/src/sound/sound.c b/src/sound/sound.c index f02e83bc5..4e0b4aa57 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -134,6 +134,9 @@ static const SOUND_CARD sound_cards[] = { { &sb_awe64_value_device }, { &sb_awe64_device }, { &sb_awe64_gold_device }, + { &sb_vibra16c_device }, + { &sb_vibra16s_device }, + { &sb_vibra16xv_device }, { &ssi2001_device }, #if defined(DEV_BRANCH) && defined(USE_PAS16) { &pas16_device },